Codeforces Round #137 (Div. 2)
A. Shooshuns and Sequence
- Find the number that goes k-th in the current sequence and add the same number to the end of the sequence;
- Delete the first number of the current sequence.
The shooshuns wonder after how many operations all numbers on the board will be the same and whether all numbers will ever be the same.
The first line contains two space-separated integers n and k (1 ≤ k ≤ n ≤ 105).
The second line contains n space-separated integers: a1, a2, ..., an (1 ≤ ai ≤ 105) — the sequence that the shooshuns found.
Print the minimum number of operations, required for all numbers on the blackboard to become the same. If it is impossible to achieve, print -1.
3 2
3 1 1
1
3 1
3 1 1
-1
In the first test case after the first operation the blackboard will have sequence [1, 1, 1]. So, one operation is enough to make all numbers the same. Thus, the answer equals one.
In the second test case the sequence will never consist of the same numbers. It will always contain at least two distinct numbers 3 and 1. Thus, the answer equals -1.
A题是一个很水的题,就是对一个序列有2种操作方法,一种是对第K个数以前的数的第一个进行删除,另一个则是在整个序列后添加这第K个数,使得整个序列为同一个数字,显然,后者是无效操作,则只需要判断第K个数以后有无与K-th不同的数,有则无解,反之有解。若有解,然后再对前面的数进行删除至全部都为第K个数为止。
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <stack> #include <memory.h> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <cstring> using namespace std; int i; int main() { int n,k; int a[1000000]; scanf("%d%d",&n,&k); for(i=1; i<=n; i++) { scanf("%d",&a[i]); } bool flag=true; for(i=k; i<=n; i++) { if(a[i]!=a[k]) { flag=false; break; } } if(!flag) { printf("-1\n"); return 0; } else { for(i=k; i>=1; i--) { if(a[i]!=a[k]) { printf("%d\n",i); return 0; } } printf("0\n"); return 0; } return 0; }
B题就是3种操作,对矩阵进行行交换、进行列交换和查询某行某列元素。
我第一次提交了一个完全模拟的代码,结果TLE。- -
然后才想起应该是标记交换的行数和列数,在查询时处理。于是h[]标记当前行交换的情况,l[]标记当前列交换的情况,h[]和l[]初始化应该保证h[i]=l[i]=i;0<=i<=m,n,查询当前第i行j列则应查询a[h[i]][l[j]]。
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <stack> #include <memory.h> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <cstring> using namespace std; int main() { //freopen("b.in","r",stdin); int i,j; int n,m,k; int a[1010][1010]; int h[1010],l[1010]; memset(a,0,sizeof(a)); scanf("%d%d%d",&n,&m,&k); for(i=0;i<1010;i++) { h[i]=i; l[i]=i; } for(i=0; i<n; i++) { for(j=0; j<m; j++) { scanf("%d",&a[i][j]); } } for(i=0; i<k; i++) { char ss; int h1,h2; scanf("%c %d %d",&ss,&h1,&h2); if(ss=='\n') { i--; continue; } h1--; h2--; if(ss=='g') { printf("%d\n",a[h[h1]][l[h2]]); } else if(ss=='c') { int fc=l[h1]; l[h1]=l[h2]; l[h2]=fc; } else if(ss=='r') { int fc=h[h1]; h[h1]=h[h2]; h[h2]=fc; } } return 0; }
CDE题暂时没看。