昨天考试考得有点迷???
一看内存限制,T1 64MB T2 16MB 当场懵比.........
T1 set
考场打的背包问题和随机化,其实能randA掉,但不小心数组开小了????(长记性!!!!!)
正解的话因为每个前缀只需mod%n,所以有n+1个数,其中一定有重复的
所以就可以O(n)扫了
其实正解不难就是没有细想
1 #include<bits/stdc++.h> 2 #define MAXN 1100 3 using namespace std; 4 int read(){ 5 int x=0;char c=getchar(); 6 while(c<'0'||c>'9')c=getchar(); 7 while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();} 8 return x; 9 } 10 int n; 11 int a[MAXN*MAXN]; 12 struct node{int id,w;}e[1000001]; 13 int ans[MAXN]; 14 int pre[MAXN][1001]; 15 bool biao[2][MAXN]; 16 void work(){ 17 for(int i=1;i<=n;++i){ 18 e[i].id=i;e[i].w=a[i]; 19 } 20 for(int i=1;i<=20000;++i){ 21 if(clock()>990000){ 22 printf("-1\n"); 23 return ; 24 } 25 random_shuffle(e+1,e+n+1); 26 int ok=0;int me=0; 27 for(int j=1;j<=n;++j){ 28 me=(me+(e[j].w%n))%n; 29 if(me==0){ 30 ok=j;break; 31 } 32 } 33 if(ok==0)continue; 34 printf("%d\n",ok); 35 for(int j=1;j<=ok;++j)printf("%d ",e[j].id); 36 return ; 37 } 38 } 39 signed main(){ 40 n=read(); 41 for(int i=1;i<=n;++i){ 42 a[i]=read();a[i]%=n; 43 } 44 if(n>1000){ 45 work(); 46 return 0; 47 } 48 int now=1;int last=0; 49 biao[last][0]=1; 50 for(int i=1;i<=n;++i){ 51 for(int j=0;j<n;++j){ 52 if(biao[last][j]){ 53 biao[now][j]=1; 54 pre[i][j]=0; 55 } 56 if(biao[last][j]){ 57 biao[now][(j+a[i])%n]=1; 58 pre[i][(j+a[i])%n]=i; 59 } 60 } 61 swap(now,last); 62 memset(biao[now],0,sizeof(biao[now])); 63 } 64 swap(now,last); 65 if(biao[now][0]==0){printf("-1\n");return 0;} 66 now=0; 67 for(int i=n;i>=1;--i){ 68 if(pre[i][now]!=0)ans[++ans[0]]=pre[i][now]; 69 now=(now-a[pre[i][now]]%n+n)%n; 70 } 71 if(ans[0]==0){printf("-1\n");return 0;} 72 printf("%d\n",ans[0]); 73 for(int i=1;i<=ans[0];++i){ 74 printf("%d ",ans[i]); 75 } 76 cout<<endl; 77 } 78 /* 79 g++ pai.cpp -o pai 80 ./pai 81 g++ a.cpp -o a 82 ./a 83 */
1 #include<bits/stdc++.h> 2 #define MAXN 1100000 3 #define int long long 4 using namespace std; 5 int vis[MAXN];int n,a[MAXN]; 6 signed main(){ 7 scanf("%lld",&n); 8 vis[0]=0; 9 for(int i=1;i<=n;++i){ 10 scanf("%lld",&a[i]); 11 }int sum=0; 12 for(int i=1;i<=n;++i){ 13 sum=(a[i]+sum)%n; 14 if(vis[sum]!=0){ 15 printf("%lld\n",i-vis[sum]); 16 for(int j=vis[sum]+1;j<=i;++j){ 17 printf("%lld ",j); 18 } 19 return 0; 20 } 21 vis[sum]=i; 22 } 23 }
T2 read
考场时看出了答案其实就是2*maxn_sum-N-1,至于证明,除非最后时只剩一种类型的书了,不然肯定能接着放
那么我们就可以直接判断了
考场没算清内存其实1e6的数据是可以开数组的
对于正解,定义一个id,cnt
我们对于每个新出现的数,当cnt=0时id=当前数,不然id=当前数cnt++;否则cnt--;
可以发现如果存在解的话,id一定为最大出现次数的值,但是因为可能中间存在非最大值之间互相抵消的情况
所以还要再扫一边,判断当前值出现次数
1 #include<bits/stdc++.h> 2 #define MAXN 1100 3 #define int long long 4 using namespace std; 5 int M,N,K; 6 int co[MAXN],x[MAXN],y[MAXN],z[MAXN];int a[MAXN]; 7 int maxn_sum=0;int maxn;int S; 8 signed main(){ 9 scanf("%lld%lld",&M,&K); 10 S=(1<<K)-1; 11 for(int i=1;i<=M;++i)scanf("%lld",&co[i]); 12 for(int i=1;i<=M;++i)scanf("%lld",&x[i]); 13 for(int i=1;i<=M;++i)scanf("%lld",&y[i]); 14 for(int i=1;i<=M;++i)scanf("%lld",&z[i]); 15 N=0;int cnt=0;int id=0; 16 for(int i=1;i<=M;++i){ 17 long long last=x[i]; 18 N++; 19 if(cnt==0){cnt=1;id=last;} 20 else if(id==last){cnt++;} 21 else if(id!=last){cnt--;} 22 for(int j=1;j<co[i];++j) { 23 last=(last*y[i]+z[i])&S; 24 N=N+1; 25 if(cnt==0){cnt=1;id=last;} 26 else if(id==last){cnt++;} 27 else if(id!=last){cnt--;} 28 } 29 } 30 if(cnt<1){printf("0\n");return 0;} 31 cnt=0;N=0; 32 for(int i=1;i<=M;++i){ 33 long long last=x[i]; 34 N++; 35 if(id==last){cnt++;} 36 for(int j=1;j<co[i];++j) { 37 last=(last*y[i]+z[i])&S; 38 N=N+1; 39 if(id==last){cnt++;} 40 } 41 } 42 if(2*cnt-N-1>0){printf("%lld\n",2*cnt-N-1);} 43 else printf("0\n"); 44 /*scanf("%lld",&N); 45 int cnt=0;int id=0; 46 for(int i=1;i<=N;++i){scanf("%lld",&a[i]);} 47 for(int i=1;i<=N;++i){ 48 long long last=a[i]; 49 if(cnt==0){cnt=1;id=last;} 50 else if(id==last){cnt++;} 51 else if(id!=last){cnt--;} printf("i=%lld\n",i); 52 } 53 if(cnt-1>0)printf("%lld\n",cnt-1); 54 else printf("%lld\n",cnt); 55 */ 56 } 57 /* 58 22 59 1 3 3 3 3 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 60 */
T3 race
咕了.............