传送门 题意:给你n个数字,其中的数字可以随机组合,问可以组合形成最多同时几个数相等 题解:找规律即可,如果n为偶数,则有n/2个,反正(n+1)/2个
#include<iostream> #include<cstring> #include<algorithm> using namespace std; int main() { int t; cin>>t; while(t--){ int n; cin>>n; cout<<(n+1)/2<<endl; } return 0; }传送门 题意:有连续的n天,她可以选择任何满足1≤k≤r的整数k,并将k天设置为一周中的天数。如果日期到达一周的最后一天,则第二天的单元格是下一行(下方)中最左边的单元格。你可以选择从一周的任意一天开始,问有多少种不同的单元格形状。 题解:画图找规律可以发现,当k<n时的不同形状的单元格个数与选择的k值相同,即和为等差数列r(1+r)/2*,k>=n的部分形状平移之后形状都是一样的,所以只需要加1; 第一种情况r<n: 输出r(1+r)/2; 第二种情况r>=n:输出(n-1)(1+n-1)/2+1;**
#include<iostream> #include<cstring> #include<algorithm> using namespace std; int main() { int t; cin>>t; while(t--){ int n,r; cin>>n>>r; if(n>r) cout<<r*1ll*(1+r)/2<<endl; else cout<<1ll*(n-1)*(1+n-1)/2+1<<endl; } return 0; }传送门 题意:有两种曲奇,数量分别为a,b,有两类人个数为n(每一个人都会选择一个数目多的那种曲奇),m(每个人都会选择一个数目少的那种曲奇),如果a=b时可以随便选一个,问是否每个人都能够拿到任意一种类型的曲奇; 题解:如果(a+b)<(n+m)时肯定有人选不到,那么如果(a+b)>=(n+m) 的情况下我们只需要先考虑第二类人m(每个人都会选择一个数目少的那种曲奇)能否都能选到,如果a,b中的最小值大于等于m,则每个人都能选到,因为第一类人n(每一个人都会选择一个数目多的那种曲奇)能够在a=b的时候随便选一个,以此下去可以选到所有的数,所以不用考虑
#include<iostream> #include<algorithm> using namespace std; long long int a,b,n,m,c; int main() { int t; cin>>t; while(t--){ cin>>a>>b>>n>>m; if((a+b)<(n+m)) cout<<"No"<<endl; //第一种情况 else{ a=min(a,b); if(a>=m) cout<<"Yes\n"; //找到最小值满足m个人需求即可 else cout<<"No\n"; } } return 0; }传送门 题解:当k能被n整除时,是可以使得每一行每一列个数相同的,如果有余数的话,把余数错开放在每行后面一个1,可以使得满足1+1=2 的情况的。 就这样构造: 上代码吧
#include<bits/stdc++.h> using namespace std; const int maxn=305; int n,k,t; int a[maxn][maxn]; int main () { scanf("%d",&t); while (t--) { scanf("%d%d",&n,&k); if (k%n==0) printf("0\n"); else printf("2\n"); int tt=0; memset(a,0,sizeof(a)); for (int i=1;i<=k/n;i++) { for (int j=0;j<n;j++) a[j][(j+tt)%n]=1; tt++; //先每行错开放k/n个,保f(A)=0; } if (k%n) for (int i=0;i<k%n;i++) a[i][(i+tt)%n]=1; //再将剩余的1错开放在前k%n行中。 for (int i=0;i<n;i++) { for (int j=0;j<n;j++) printf("%d",a[i][j]); printf("\n"); } } return 0; }传送门 题解:让我们来定义m=max(a1,a2,…,an).
玉祖至少应该m−n+1糖果最初是为了赢得所有决斗,然后f(x)=0为x<m−n+1。这可以被p.
如果五十铃有相等的或更多的.m糖果一开始,任何排列都是有效的,然后f(x)=n!为x≥m。这可以被p也是。(因为p≤n)
然后,在这个子任务中,您应该找到每个f(x)可被p为m−n+1≤x<m在……里面O(n).
您可以找到f(x)通过以下模拟:
首先,让v={他们的敌人数量严格地少于x糖果),ans=1. 然后执行以下步骤i=x,x+1,…,x+(n−1). v=v+{他们有多少敌人i糖果) ans=ans∗v v=v−1 现在,p是个质数。然后,“是否f(x)可被p“是”是否p乘成ans如v至少有一次。“
这可以在O(n)每个人的时间x.
总复杂性:O(n2)
#include<stdio.h> int max(int a,int b){if(a>b){return a;}return b;} int main(){ int n,p; int st,fi; int a[131072],bk[262144]={0},bas=0,i,j; int res[131072],rc=0; scanf("%d%d",&n,&p); for(i=0;i<n;i++){ scanf("%d",&a[i]); bas=max(a[i],bas); } for(i=0;i<n;i++){bk[max(0,a[i]-bas+n)]++;} for(i=1;i<262144;i++){bk[i]+=bk[i-1];} for(i=0;i<=n;i++){ for(j=0;j<n;j++){ if((bk[i+j]-j)<=0){break;} if((bk[i+j]-j)%p==0){break;} if(j==n-1){res[rc]=i+(bas-n);rc++;} } } printf("%d\n",rc); for(i=0;i<rc;i++){ if(i){printf(" ");} printf("%d",res[i]); }printf("\n"); }传送门 题解:
#include<stdio.h> int max(int a,int b){if(a>b){return a;}return b;} int main(){ int n,p; int st,fi; int a[131072],bk[262144]={0},bas=0,i; scanf("%d%d",&n,&p); for(i=0;i<n;i++){ scanf("%d",&a[i]); bas=max(a[i],bas); } for(i=0;i<n;i++){bk[max(0,a[i]-bas+n)]++;} for(i=1;i<262144;i++){bk[i]+=bk[i-1];} st=1; for(i=1;i<=n;i++){ while(bk[st+(i-1)]<i){st++;} } st+=(bas-n); fi=n; for(i=1;i<=n;i++){ while(fi>0){ if(bk[fi+(i-1)]-(i-1)<p){break;} fi--; } } fi+=(bas-n); if(st>fi){ printf("0\n\n"); return 0; } printf("%d\n",fi-st+1); for(i=st;i<=fi;i++){ if(i!=st){printf(" ");} printf("%d",i); }printf("\n"); return 0; }