A
感觉A比较复杂啊,相比较B简单明了。
way1
只要有相同的一个数,它的数目大于等于k,那么它就可以进行一次操作,接下来可以再摸k-1个数,那么对于无法凑成k个数的数字来说,无论现在它有多少个数(>=1),加上这k-1个数,都能凑成数目>=k。同时,这个操作可以无限循环下去。
所以这道题的出题设计还是比较精妙的。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned long long 5 6 const LL mod_1=1e9+7; 7 const LL mod_2=998244353; 8 9 const double eps_1=1e-5; 10 const double eps_2=1e-10; 11 12 const int maxn=2e5+10; 13 14 map<int,int> m; 15 16 int main() 17 { 18 int T,n,k,d,i,x,y,z,result; 19 scanf("%d",&T); 20 while (T--) 21 { 22 x=y=z=0; 23 result=0; 24 m.clear(); 25 26 scanf("%d%d",&n,&k); 27 for (i=0;i<n;i++) 28 { 29 scanf("%d",&d); 30 m[d]++; 31 } 32 33 for (auto par:m) 34 { 35 x += par.second / k * (k-1); 36 //y += (k-1) - (k - par.second%k); 37 y += max(par.second%k - 1, 0); 38 z += par.second; 39 } 40 41 if (x==0) 42 result=z; 43 else 44 { 45 result = x+y; 46 while (result>=k) 47 result = result%k + result/k*(k-1); 48 } 49 50 //printf("Case %d : ",T); 51 printf("%d\n",result); 52 } 53 54 return 0; 55 }
way2
A 数目大于等于k的数,记录可以执行变化的操作数目,对应可以摸的数目
B 数目小于k的数,从大到小排序,依次利用A摸到的数,增加这个数的数目,看能否数目到达k个,然后可以归类为A
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned long long 5 6 const LL mod_1=1e9+7; 7 const LL mod_2=998244353; 8 9 const double eps_1=1e-5; 10 const double eps_2=1e-10; 11 12 const int maxn=2e5+10; 13 14 map<int,int> m; 15 vector<int> vec(1005); 16 17 int main() 18 { 19 int T,n,k,d,i,rest,result; 20 scanf("%d",&T); 21 while (T--) 22 { 23 rest=0; 24 result=0; 25 m.clear(); 26 vec.clear(); 27 28 scanf("%d%d",&n,&k); 29 for (i=0;i<n;i++) 30 { 31 scanf("%d",&d); 32 m[d]++; 33 } 34 35 for (auto par:m) 36 { 37 rest += (par.second / k) * (k-1); 38 vec.push_back( par.second % k ); 39 } 40 41 sort(vec.begin(), vec.end()); 42 reverse(vec.begin(), vec.end()); 43 //result += accumulate(vec.begin(), vec.end(), 0); 44 45 for (auto v:vec) 46 if (rest >= k - v) 47 { 48 rest += k-1 - (k-v); 49 } 50 else 51 result+=v; 52 53 while (rest>=k) 54 rest = rest%k + rest/k*(k-1); 55 result+=rest; 56 57 //printf("Case %d : ",T); 58 printf("%d\n",result); 59 } 60 61 return 0; 62 }
B
对于某个颜色,
行的最小=1,最大=n
列的最小=1,最大=m
只要满足这个条件就行,无论黑色还是白色
好的代码写法能很快写完
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned long long 5 6 const LL mod_1=1e9+7; 7 const LL mod_2=998244353; 8 9 const double eps_1=1e-5; 10 const double eps_2=1e-10; 11 12 const int maxn=2e5+10; 13 14 int main() 15 { 16 int T,n,m,i,j,u1,u2,u3,u4,v1,v2,v3,v4; 17 char c; 18 //xmin,xmax,ymin,ymax 19 scanf("%d",&T); 20 while (T--) 21 { 22 u1=u2=u3=u4=v1=v2=v3=v4=0; 23 scanf("%d%d",&n,&m); 24 for (i=1;i<=n;i++) 25 { 26 scanf("%c",&c); 27 for (j=1;j<=m;j++) 28 { 29 scanf("%c",&c); 30 if (c=='W') 31 { 32 if (i==1) 33 u1=1; 34 if (i==n) 35 u2=1; 36 if (j==1) 37 u3=1; 38 if (j==m) 39 u4=1; 40 } 41 else 42 { 43 if (i==1) 44 v1=1; 45 if (i==n) 46 v2=1; 47 if (j==1) 48 v3=1; 49 if (j==m) 50 v4=1; 51 } 52 } 53 } 54 //printf("Case %d : ",T); 55 if ((u1+u2+u3+u4==4) || (v1+v2+v3+v4==4)) 56 printf("YES\n"); 57 else 58 printf("NO\n"); 59 } 60 61 return 0; 62 }
C
D
n的要求才1e6,所以可以大开大合的构造:
对于不能为k
a. 1、2、4、... 相加,直到小于等于(k-1)。 这些数的和为A。
b. (k-1)-A。 使得a、b这两类数的和为(k-1),同时,可以任意数相加和可以为1~(k-1)。
c. k+1、k+2、k+3 三个数。a、b、c这三类数,可以任意数相加和可以为1~(2*k-1)。 这个就是大致构造,大致感觉可以就行。
d. k*2、k*4、k*8、... 剩余凑齐25个数。
不要对于比较小的k,都制定一组数,这样工作量大,很累,很容易出错,浪费大量时间。n<=1e6太小了,完全有很多选择,浪费多一两个数,也能构造出成功、设计很简单的例子。
通过k=1~15,看结果,判断是否可以。assert(最后一个数>=5e5)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned long long 5 6 const LL mod_1=1e9+7; 7 const LL mod_2=998244353; 8 9 const double eps_1=1e-5; 10 const double eps_2=1e-10; 11 12 const int maxn=2e5+10; 13 14 int er[100],result[100]; 15 16 int main() 17 { 18 int T,n,k,m,i,j,maxs=25; 19 er[0]=1; 20 for (i=1;er[i-1]<=1e7;i++) 21 er[i]=er[i-1]<<1; 22 scanf("%d",&T); 23 while (T--) 24 { 25 scanf("%d%d",&n,&k); 26 m=k-1; 27 i=0; 28 j=0; 29 while (m>=er[i]) 30 { 31 result[j++]=er[i]; 32 m-=er[i]; 33 i++; 34 } 35 if (m>0) 36 result[j++]=m; 37 result[j++]=k+1; 38 result[j++]=k+2; 39 result[j++]=k+3; 40 41 result[j++]=k*2; 42 while (j<maxs) 43 { 44 result[j]=result[j-1]*2; 45 j++; 46 } 47 48 //assert(result[maxs-1]>1e6); 49 50 printf("%d\n",maxs); 51 52 for (i=0;i<maxs;i++) 53 { 54 printf("%d",result[i]); 55 if (i==maxs-1) 56 printf("\n"); 57 else 58 printf(" "); 59 } 60 } 61 62 return 0; 63 } 64 /* 65 15 66 1 1 67 1 2 68 1 3 69 1 4 70 1 5 71 1 6 72 1 7 73 1 8 74 1 9 75 1 10 76 1 11 77 1 12 78 1 13 79 1 14 80 1 15 81 */
标签:10,const,int,LL,cf941,long,941,result,Div From: https://www.cnblogs.com/cmyg/p/18176017