昨天做的多校题目。
题目大概就是说有n*m的一个方格,其中k个格子里放了数字。然后进行q个操作,1是交换列,2是交换行,3是查询当前x,y有什么数字,没有输出0。
题目不难,但是写起来有点别扭。主要的思想是hash。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; #define maxn 100010 struct N { int x, y, val; } node[maxn]; int x[maxn], y[maxn]; int xx[maxn], yy[maxn]; int changex[maxn], changey[maxn]; int n, m, k; void solve1() { int q; cin >> q; while(q--) { int a, b, c; scanf("%d%d%d", &a, &b, &c); if(a == 3) puts("0"); } return ; } int find(int qq[], int q, int tk) { // for(int i = 0; i < tk; i ++) // cout << qq[i] << endl; int l = lower_bound(qq, qq+tk, q) - qq; int r = upper_bound(qq, qq+tk, q) - qq; // cout << qq[l] << " " << qq[r] << " " << q << endl; if(l > r) return -1; if(l == r-1) return l; else while(1) l++; } int solve(int qx, int qy) { qx = changex[qx]; qy = changey[qy]; int l = lower_bound(x, x+k, xx[qx]) - x; int r = upper_bound(x, x+k, xx[qx]) - x; r--; qy = yy[qy]; while(l <= r) { int m = (l + r) / 2; if(node[m].y > qy) r = m-1; else if(node[m].y < qy) l = m+1; else return node[m].val; } return 0; } bool cmp(N a, N b) { if(a.x == b.x) return a.y < b.y; return a.x < b.x; } int main() { // f//reopen("in.txt", "r", stdin); //freopen("out(2).txt", "w", stdout); int t; cin >> t; for(int Ca = 1; Ca <= t; Ca++) { scanf("%d%d%d", &n, &m, &k); for(int i = 0; i < k; i++) { scanf("%d%d%d", &node[i].x, &node[i].y, &node[i].val); x[i] = node[i].x; y[i] = node[i].y; } printf("Case #%d:\n", Ca); sort(node, node + k, cmp); sort(x, x + k); sort(y, y + k); if(!k) { solve1(); continue; } xx[0] = x[0]; int sumx = 1; for(int i = 1; i < k; i++) if(x[i] != x[i-1]) xx[sumx++] = x[i]; yy[0] =y[0]; int sumy = 1; for(int i = 1; i < k; i++) if(y[i] != y[i-1]) yy[sumy++] = y[i]; for(int i = 0; i < sumx; i++) changex[i] = i; for(int i = 0; i < sumy; i++) changey[i] = i; int q; cin >> q; while(q--) { int a, b, c; scanf("%d%d%d", &a, &b, &c); //cout << a << " " << b << " " << c << endl; if(a == 2) { b = find(yy, b, sumy); c = find(yy, c, sumy); if(b == -1 && c == -1) continue; swap(changey[b], changey[c]); } else if(a == 1) { b = find(xx, b, sumx); c = find(xx, c, sumx); //cout << a << " " << b << " " << c << endl; if(b == -1 && c == -1) continue; swap(changex[b], changex[c]); } else { b = find(xx, b, sumx); c = find(yy, c, sumy); if(b == -1 || c == -1) puts("0"); else printf("%d\n", solve(b, c)); } } } }
开始的时候WA了几发,因为upper_bound(), 返回的是大于键值的第一个位置,我以为是小于等于键值的第一个位置。。。
真心跪了,我这基础是有多不扎实啊。
原文:http://www.cnblogs.com/ye8370/p/3909202.html