Codeforces Round #269 (Div. 2)
A
题意:给出6根木棍,如果有4根相同,2根不同,则构成“bear”,如果剩余两个相同,则构成“elephant”
用一个数组分别储存各个数字出现的次数,再判断即可
注意hash[i]==5的时候,也算作bear,因为它也是满足了4根相同,2根不同
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<queue> 9 #include<algorithm> 10 #define mod=1e9+7; 11 using namespace std; 12 13 typedef long long LL; 14 int hash[1005],a[10]; 15 16 int main(){ 17 int i,j,ans=0; 18 memset(hash,0,sizeof(hash)); 19 for(i=0;i<6;i++){ 20 cin>>a[i]; 21 hash[a[i]]++; 22 } 23 24 int x=0,y=0; 25 for(i=1;i<=9;i++){ 26 if(hash[i]){ 27 if(hash[i]==4||hash[i]==6||hash[i]==5) x=1; 28 if(hash[i]==2||hash[i]==6) y=1; 29 } 30 } 31 32 if(x&&y) printf("Elephant\n"); 33 else if(x==1&&y!=1) printf("Bear\n"); 34 else printf("Alien\n"); 35 }
B
题意:给出n个数,按照从小到大的难度级别排序,问是否存在3种及三种以上这样的排序序列
这一题自己没想出来,想得还很复杂= =觉得好乱= = 不过后来看了题解,
发现这样就可以了,再用另一个b数组记录下来相同的数的位置,如果b数组的大小小于等于1,一定不满足
反之,只要b数组里面有两个数,我们就可以通过交换这两个位置(本身排出来有一个序列,分别交换两个位置可以得到两个),得到3个排序序列
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<queue> 9 #include<algorithm> 10 #define mod=1e9+7; 11 using namespace std; 12 13 typedef long long LL; 14 const int maxn=2000+5; 15 int b[maxn]; 16 17 struct node{ 18 int h; 19 int pos; 20 } a[maxn]; 21 22 int cmp(node n1,node n2){ 23 if(n1.h!=n2.h) return n1.h<n2.h; 24 return n1.pos<n2.pos; 25 } 26 27 int main(){ 28 int n,i,j,cnt; 29 cin>>n; 30 for(i=1;i<=n;i++){ 31 cin>>a[i].h; 32 a[i].pos=i; 33 } 34 35 sort(a+1,a+n+1,cmp); 36 cnt=0; 37 38 for(i=2;i<=n;i++){ 39 if(a[i].h==a[i-1].h){ 40 b[cnt++]=i-1; 41 } 42 } 43 if(cnt<=1) printf("NO\n"); 44 else{ 45 printf("YES\n"); 46 for(i=1;i<n;i++) 47 printf("%d ",a[i].pos); 48 printf("%d\n",a[i].pos); 49 50 swap(a[b[0]],a[b[0]+1]); 51 52 for(i=1;i<n;i++) 53 printf("%d ",a[i].pos); 54 printf("%d\n",a[i].pos); 55 56 // swap(a[b[0]],a[b[0]+1]);//这个地方叫交不交换都可以,交换了即为将第一个位置的换回来,都是不一样的序列 57 swap(a[b[1]],a[b[1]+1]); 58 59 for(i=1;i<n;i++) 60 printf("%d ",a[i].pos); 61 printf("%d\n",a[i].pos); 62 } 63 return 0; 64 }
C
题意:给出n个木棍,问能够搭成多少个不同高度的房子
首先想到的是算怎样消耗最少并且能够搭起最高的房子,
观察图可得:横杠之间有n个空隙,就会对应n+1个类似“八”的2根木棒,
这里的第几层是从最高层往最低层数 所以
第0层,0根横杠:1
第1层,1根横杠::1+(1+1)*2 -
第2层,2根横杠:2+(2+1)*2
第i层,i根横杠:i+(i+1)*2=3*i+2
即为满足这样的等差数列就可以消耗最小的房子
然后求前i项和:i*2+(i*(i-1))/2=i*(3*i+1)/2
然后就是自己的doubi思路:想的是,建成最高的了,然后就一层一层得往下拆,看可以拆成多少个高度不同的房子= =一直写不出来
正确的应该是这样:从i=1开始枚举,枚举到i*(3*i+1)/2<=n,这样即为完成消耗最小的房子,
又因为不能有木棒剩余,所以只能3根3根地加, 所以只需要满足n-(i*(3*i)+1)/2能够整除3即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<queue> 9 #include<algorithm> 10 #define mod=1e9+7; 11 using namespace std; 12 13 typedef long long LL; 14 LL n; 15 LL ans,tmp,row,sum=0; 16 17 int main(){ 18 cin>>n; 19 for(LL i=1;(tmp=(3*i+1)*i/2)<=n;i++){ 20 21 if((n-tmp)%3==0) 22 ans++; 23 } 24 cout<<ans<<"\n"; 25 return 0; 26 }