Codeforces Beta Round #107(Div2)-5/15补题报告
链接:https://codeforces.com/problemset/problem/151/B
题意:
从形如“XX-XX-XX”由数字构成的电话号码中寻找分别拥有每种类型的电话号码的最大数量的朋友,
出租车号码由6个相同的数字组成(例如,22-22-22),
送披萨的数量必须是6个不同的数字的递减序列(例如,98-73-21),(是三个数字递减,不要入坑以为六个数字依次递减)
其他所有的数字都是女孩的数字。
解题思路:
构造结构体数组,分别存储每个朋友的姓名,编号以及三种电话类型数量,构造cmp分别对其排序,
输出的时候要注意格式,具有最多相同类型数量的朋友全部输出。
ac代码:
#include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<map> #include<vector> #include<string> using namespace std; struct node{ string name; int id; int taxi,pizza,girl; }z[110]; int cmp1(node a,node b){ if(a.taxi==b.taxi) return a.id<b.id; return a.taxi>b.taxi; } int cmp2(node a,node b){ if(a.pizza==b.pizza) return a.id<b.id; return a.pizza>b.pizza; } int cmp3(node a,node b){ if(a.girl==b.girl) return a.id<b.id; return a.girl>b.girl; } int main(){ int n,k,i,j,x,y,zz,flag; cin>>n; for(i=0;i<n;i++){ cin>>k>>z[i].name; z[i].id=i; for(j=0;j<k;j++){ scanf("%d-%d-%d",&x,&y,&zz); if((x%10==x/10)&&x==y&&y==zz){ z[i].taxi++; } else if(x/10>x%10&&x%10>y/10&&y/10>y%10&&y%10>zz/10&&zz/10>zz%10){ z[i].pizza++; } else{ z[i].girl++; } } } cout<<"If you want to call a taxi, you should call: "; sort(z,z+n,cmp1); flag=0; for(i=0;i<n;i++){ if(z[i].taxi!=z[0].taxi){ break; } if(flag){ cout<<", "; } cout<<z[i].name; flag++; } cout<<"."<<endl; sort(z,z+n,cmp2); cout<<("If you want to order a pizza, you should call: "); flag=0; for(i=0;i<n;i++){ if(z[i].pizza!=z[0].pizza){ break; } if(flag){ cout<<", "; } cout<<z[i].name; flag++; } cout<<"."<<endl; sort(z,z+n,cmp3); cout<<("If you want to go to a cafe with a wonderful girl, you should call: "); flag=0; for(int i=0;i<n;i++){ if(z[i].girl!=z[0].girl){ break; } if(flag){ cout<<", "; } cout<<z[i].name; flag++; } cout<<"."<<endl; return 0; }
C - Win or Freeze
链接:https://codeforces.com/problemset/problem/151/C
题意:
给一个数n,两人轮流操作,
每次将n变为一个n的非1非自身的因数,第一个无法进行操作的人获胜,
问第一位是否有必胜策略,如果有的话在第二行输出第一步换成哪个数,如果第一步就不能操作则输出0;第二位赢则直接输出2。
思路:
当n为1或者质数时,先手胜且输出0;
当n恰为两个质数的乘积时,先手负,因为他只能写下一个质数,使后手获胜;
其他情况下,他只要写下n的任意两个质因数的乘积就能获胜。
ac代码:
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> using namespace std; int main(){ long long int q,i; vector<long long int>v; v.clear(); cin>>q; for(i=2;i*i<=q;i++){ while(q%i==0){ v.push_back(i); q=q/i; } } if(q>1){ v.push_back(q); } if(v.size()<2){ cout<<"1"<<endl; cout<<"0"<<endl; } else if(v.size()==2){ cout<<"2"<<endl; } else{ cout<<"1"<<endl; cout<<v[0]*v[1]<<endl; } return 0; }
D - Quantity of Strings
链接:https://codeforces.com/problemset/problem/151/D
题意:用m种字符,构成长度为n的串,使得所有长度为K的串都为回文串,求有多少种方法。
思路:
分以下几种情况:
1、k<n&&k%2==0 此时串中只能有一种字符
2、k==n (k为奇数,最中间的字符为任意,然后考虑左边或者右边,一边的每个位可以为任意字符) (k位偶数,考虑一边即可)
3、k>n||k==1 每个位可以位任意字符 (要注意k>n)
4、k为其他情况,(n为奇数,如同ababa这样或者aaaaa,每个字符串只能有一种或两种字符,即m*m) (n为偶数则字符串只能有一种字符)
ac代码:
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<map> #include<set> using namespace std; int main(){ int n,m,k,i; long long ans; while(~scanf("%d%d%d",&n,&m,&k)) { if(k<n&&k%2==0){ cout<<m<<endl; continue; } ans=1; if(k==n){ if(n%2){ ans=m; for(i=1;i<=k/2;i++) ans=ans*m%1000000007; } else{ for(i=1;i<=k/2;i++) ans=ans*m%1000000007; } } else if(k==1||k>n) { for(i=1;i<=n;i++) ans=ans*m%1000000007; } else { if(!n%2) ans=m; else ans=m*m; } cout<<ans<<endl; } return 0; }