吹爆这一场,第一次打到这么前,虽然赛后打得

每次增多(i-1)*4个
他的操作真正的意思就是,变负数绝对值+1,变正数绝对值+1
所以说我们保证有最多的偶数个负数就好了
注意,如果奇数个0,那就是0了
如果有偶数个数,全变成负数
奇数个数,就留一个正数,(先都变成负数,然后把绝对值最大的那个数变成正数)自己举几个例子能看出变绝对值最大的
可以发现
执行N次之后,留在开头的是最大的数,后面是除去最大的数的一个排列
再往后执行就是循环的过程了,从后面的数中拿一个放到末尾,拿一个放到末尾(循环节N-1)
所以我们只要模拟执行一下前N次,然后找到后面数的排列,记住前N次的取法就好了
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| LL T,N,M,K;
struct AandB { int a,b; }c[MAX]; int d[2*MAX];
int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> N >> T; for(int i = 1;i <= N;i++) { cin >> d[i]; } int head,pos,time; head = max(d[1],d[2]); time = 1; pos = N+1; AandB temp; temp.a = d[1]; temp.b = d[2]; c[time++] = temp; d[pos++] = min(d[1],d[2]); for(int i = 3;i <= N;i++) { temp.a = head; temp.b = d[i]; c[time++] = temp; d[pos++] = min(head,d[i]); head = max(head,d[i]); } vector<int> f; for(int i = N+1;i < pos;i++) { f.push_back(d[i]); } while(T--) { cin >> M; if(M < time) { cout << c[M].a << " " << c[M].b <<endl; } else { cout << head << " " << f[(M - N) % (N-1)] <<endl; } } return 0; }
|
题目思路:
题意就是你把N*M的各自每一个走一遍并且你的跳(A -> B)的时候的(Xa-Xb,Ya-Yb)也是不能重复的
那么把格子抽象为点,走一步画一条线,画的这个线不能有平行且长度相等的
当当当,然后我就发现
(1,1) - (n,m) - (1,2) - (n,m-1) -……(n,1)
(2,1)- (n-1,m) -……(n-1,1)
不同俩行匹配 保证了dert Y是不一样的
相同俩行时 又保证了 dert X 不同
如果n是奇数就需要中间那一行前后匹配一下
题目代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| int T,N,M,K;
int main() {
scanf("%d%d",&N,&M); int j = N; int r; for(int i = 1;i <= j;i++,j--) { if(j == i) { r = M; for(int l = 1;l <= r;l++,r--) { if(l == r) printf("%d %d\n",i,r); else { printf("%d %d\n",i,l); printf("%d %d\n",i,r); } } } else { r = M; for(int l = 1;l <= M;l++,r--) { printf("%d %d\n",i,l); printf("%d %d\n",j,r); } } } return 0; }
|