http://codeforces.com/gym/100623/attachments
A题
B题
题意:给你一个长度为w有h个单位宽的广告牌,然后给你长度为 wi 的一个单位宽的广告,问第 i 个最低能放在哪个单位上,如果不存在打印-1.
思路:一道线段树的问题,套用线段树模板就能很简单的解答了。比赛的时候没有想到用线段树真是好心塞啊
1 #include <iostream> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn=200005; 5 struct node 6 { 7 int l,r,cnt; 8 } a[maxn<<2]; 9 void build(int l,int r,int k,int m) 10 { 11 a[k].l=l,a[k].r=r,a[k].cnt=m; 12 if(l==r) 13 return ; 14 int mid=(l+r)/2; 15 build(l,mid,k<<1,m); 16 build(mid+1,r,k<<1|1,m); 17 return ; 18 } 19 void init(int k,int d) 20 { 21 22 if(a[k].l==a[k].r) 23 { 24 a[k].cnt=a[k].cnt-d; 25 printf("%d ",a[k].l); 26 return ; 27 } 28 if(a[k*2].cnt>=d) 29 init(k*2,d); 30 else if(a[k*2+1].cnt>=d) 31 init(k*2+1,d); 32 a[k].cnt=max(a[k*2].cnt,a[k*2+1].cnt); 33 return ; 34 35 } 36 int main() 37 { 38 freopen("billboard.in","r",stdin); 39 freopen("billboard.out","w",stdout); 40 int n,m,k,x; 41 while(~scanf("%d%d%d",&n,&m,&k)) 42 { 43 int p=min(n,k); 44 build(1,p,1,m); 45 for(int i=0; i<k; i++) 46 { 47 scanf("%d",&x); 48 if(a[1].cnt<x) 49 printf("-1 "); 50 else 51 init(1,x); 52 } 53 } 54 return 0; 55 }
C题
题意:给你学生的数量和一间教室的座位的行数和列数,问你如何让学生入座才能使得行的最大值和列的最大值的最小值最大?打印此时入座方式。
思路:简单思维题,细想一下就能知道:当人数大于等于行数和列数的最小值的二倍减一时结果是行数和列数的最小值,否则是如果是偶数结果是人数的一半,若是奇数结果就是人数的一半加一。然后把单字符数组填一下就可以了。
1 #include <iostream> 2 #include <bits/stdc++.h> 3 using namespace std; 4 char s[1005][1005]; 5 int main() 6 { 7 freopen("class.in","r",stdin); 8 freopen("class.out","w",stdout); 9 int n,m,k; 10 while(~scanf("%d%d%d",&k,&n,&m)) 11 { 12 memset(s,'.',sizeof(s)); 13 int x=min(n,m); 14 if(x*2-1<=k) 15 { 16 printf("%d ",x); 17 for(int i=0; i<x; i++) 18 s[i][0]='#'; 19 for(int i=1; i<x; i++) 20 s[0][i]='#'; 21 k=k-x*2+1; 22 for(int i=1; i<n; i++) 23 { 24 for(int j=1; j<m; j++) 25 { 26 if(k==0) 27 break; 28 s[i][j]='#'; 29 k--; 30 } 31 } 32 if(k>0) 33 { 34 for(int i=m-1; i>=x; i--) 35 { 36 if(k==0) 37 break; 38 s[0][i]='#'; 39 k--; 40 } 41 } 42 if(k>0) 43 { 44 for(int i=n-1; i>=x; i--) 45 { 46 if(k==0) 47 break; 48 s[i][0]='#'; 49 k--; 50 } 51 } 52 for(int i=0; i<n; i++) 53 { 54 for(int j=0; j<m; j++) 55 printf("%c",s[i][j]); 56 printf(" "); 57 } 58 } 59 else 60 { 61 if(k%2==0) 62 { 63 printf("%d ",k/2); 64 for(int i=0; i<k/2; i++) 65 s[i][0]='#'; 66 k=k-k/2; 67 for(int j=1; j<k+1; j++) 68 s[0][j]='#'; 69 for(int i=0; i<n; i++) 70 { 71 for(int j=0; j<m; j++) 72 printf("%c",s[i][j]); 73 printf(" "); 74 } 75 } 76 else 77 { 78 printf("%d ",k/2+1); 79 for(int i=0; i<k/2+1; i++) 80 s[i][0]='#'; 81 for(int j=0; j<k/2+1; j++) 82 s[0][j]='#'; 83 for(int i=0; i<n; i++) 84 { 85 for(int j=0; j<m; j++) 86 printf("%c",s[i][j]); 87 printf(" "); 88 } 89 } 90 } 91 } 92 return 0; 93 }
D题
E题
F题
G题
H题
题意:给你孔的数量n,其中打印0、4、6、9能打印出一个孔,打印8能打印出两个孔,其他数字不能打印出孔。问打印出n个孔的最小的数是啥?
思路:简单题,读懂题后很容易知道:处理特殊值n==0时应该是1,n==1时应该是0,其他的如果n%2==0是就是n/2个8,n%2==1时先打印4在打印n/2个8;
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <bits/stdc++.h> 5 #include <algorithm> 6 using namespace std; 7 typedef long long ll; 8 ll a[500],ans[500]; 9 int main() 10 { 11 freopen("holes.in","r",stdin); 12 freopen("holes.out","w",stdout); 13 int n; 14 while(~scanf("%d",&n)) 15 { 16 if(n==0) 17 { 18 printf("1 "); 19 } 20 else if(n==1) 21 { 22 printf("0 "); 23 } 24 else if(n%2==1) 25 { 26 printf("4"); 27 for(int i=0;i<n/2;i++) 28 printf("8"); 29 printf(" "); 30 } 31 else 32 { 33 for(int i=0;i<n/2;i++) 34 printf("8"); 35 printf(" "); 36 } 37 } 38 return 0; 39 }
I题
J题
K题
题意:给你n和m,然后给你n个数字,让你给出m个数字让这m+n个数字一定能组成1~22之间的任意一个数。
思路:这个题的思想真的很重要。首先看n个数是否缺少 1 ,如果缺少的话立即补上。然后在1~x全部能够组成的前提下,下一个数 t 如果在1~x之间则就能够组成了1~(x+t)之间的数,然后按照这个过程进行下一次组数,一直到m个数用完结束
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <bits/stdc++.h> 5 #include <algorithm> 6 using namespace std; 7 typedef long long ll; 8 ll a[500],ans[500]; 9 int main() 10 { 11 //freopen("key.in","r",stdin); 12 //freopen("key.out","w",stdout); 13 14 ll n,m; 15 while(scanf("%lld%lld",&n,&m)!=-1) 16 { 17 for(int i=0; i<n; i++) 18 { 19 scanf("%lld",&a[i]); 20 } 21 sort(a,a+n); 22 ll tmp=1,flag,j=1; 23 ll ss=n; 24 long long sum=0; 25 if(a[0]!=1) 26 { 27 a[ss]=1; 28 ss++; 29 sort(a,a+ss); 30 ans[j]=1; 31 m--; 32 j++; 33 } 34 for(int i=0; i<ss&&m>0; i++) 35 { 36 sum+=a[i]; 37 if(sum<a[i+1]-1) 38 { 39 ans[j]=sum+1; 40 j++; 41 m--; 42 a[ss]=sum+1; 43 ss++; 44 sort(a,a+ss); 45 } 46 } 47 sum=0; 48 for(int i=0; i<ss; i++) 49 sum+=a[i]; 50 while(m>0) 51 { 52 ans[j]=sum+1; 53 sum=ans[j]+sum; 54 j++; 55 m--; 56 } 57 for(int i=1; i<j; i++) 58 { 59 if(i!=j-1) 60 printf("%lld ",ans[i]); 61 else 62 printf("%lld ",ans[i]); 63 } 64 65 } 66 return 0; 67 }