Codeforces Round #404 (Div. 2)解题报告
A,B都没什么可说的,直接贴代码
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <cstring> 7 #include <string> 8 #include <vector> 9 #include <map> 10 #include <queue> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned long long ull; 14 const int MAX=1e5+5; 15 map <string,int>x; 16 int main() 17 { 18 x["Tetrahedron"]=4; 19 x["Cube"]=6; 20 x["Octahedron"]=8; 21 x["Dodecahedron"]=12; 22 x["Icosahedron"]=20; 23 int n; 24 ll an=0; 25 // scanf("%d",&n); 26 cin>>n; 27 while(n--) 28 { 29 string s; 30 cin>>s; 31 an+=x[s]; 32 } 33 cout<<an<<"\n"; 34 35 }
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <cstring> 7 #include <string> 8 #include <vector> 9 #include <map> 10 #include <queue> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned long long ull; 14 const ll MAX=2e5+5; 15 const ll INF=1e9+5; 16 ll n,m; 17 ll kai1=-1,jie1=INF,kai2=-1,jie2=INF; 18 ll x,y; 19 ll an1,an2; 20 int main() 21 { 22 // scanf("%d",&n); 23 cin>>n; 24 while(n--) 25 { 26 cin>>x>>y; 27 kai1=max(x,kai1); 28 jie1=min(y,jie1); 29 // cout<<x<<endl<<y<<endl; 30 } 31 cin>>m; 32 while(m--) 33 { 34 cin>>x>>y; 35 kai2=max(x,kai2); 36 jie2=min(y,jie2); 37 } 38 // cout<<kai1<<endl<<jie1<<endl<<kai2<<endl<<jie2<<endl; 39 if(jie1>=kai2) 40 { 41 an1=0; 42 } 43 else 44 an1=kai2-jie1; 45 if(jie2>=kai1) 46 { 47 an2=0; 48 } 49 else 50 an2=kai1-jie2; 51 cout<<max(an1,an2)<<"\n"; 52 // cout<<an2<<"\n"<<an1; 53 return 0; 54 }
C
二分寻找答案,第x天吃x个,只要某天开始时剩的小于当时的天数,就说明目标日期为那一天或在那一天之前
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <cstring> 7 #include <string> 8 #include <vector> 9 #include <map> 10 #include <queue> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned long long ull; 14 ll n,m; 15 ll na; 16 ll bs() 17 { 18 ll l,r,mid; 19 ll tem; 20 ll an=-1; 21 l=m+1; 22 r=m+2e9; 23 while(l<=r) 24 { 25 mid=(l+r)/2; 26 tem=n-(mid-m-1)*(mid-m)/2; 27 // cout<<mid<<endl; 28 if(tem<=mid) 29 { 30 an=mid; 31 r=mid-1; 32 } 33 else 34 l=mid+1; 35 } 36 return an; 37 } 38 int main() 39 { 40 cin>>n>>m; 41 // cout<<n<<" "<<m<<endl; 42 if(m>=n) 43 cout<<n<<"\n"; 44 else 45 { 46 cout<<bs()<<"\n"; 47 } 48 }
D
真的好遗憾没有在比赛时过这道题……
设x为从左到此处左括号个数,y为从右到此右括号个数,则加上x+y-1Cy个,因为这个位置的这个括号是一定要取的(仔细想一想,不然的话如果按x+yCy算会出现重复情况,到每一个位置的与其他选择区分的方法就是左括号最右的一个为当下这个位置的左括号)其中因为模的是质数,且考虑到数据范围,预处理阶乘、用快速幂求逆元(利用费马小定理,求最后一个就行,有递推公式),将这些值都准备好,算组合数的值时几乎就是O(1)的了。(比赛时用Lucas定理T的不行……还是经验不够啊)
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <cstring> 7 #include <string> 8 #include <vector> 9 #include <map> 10 #include <queue> 11 using namespace std; 12 typedef long long LL; 13 const LL MOD=1e9+7; 14 const int MAX=4e5+5; 15 LL fi[MAX],inv[MAX]; 16 LL len; 17 LL quick(LL a,LL b)//a��b���� 18 { 19 LL an=1LL; 20 while(b) 21 { 22 if(b&1) 23 { 24 an=an*a%MOD; 25 } 26 a=a*a%MOD; 27 b/=2; 28 } 29 return an%MOD; 30 } 31 LL C(LL a,LL b) 32 { 33 if(a<0||b<0) 34 return 0LL; 35 return (fi[a]*inv[b]%MOD)*inv[a-b]%MOD; 36 } 37 char a[200005]; 38 LL ge1,ge2,re; 39 int main() 40 { 41 cin>>a; 42 ge1=ge2=re=0; 43 len=strlen(a); 44 for(LL i=0;i<=2*len;i++) 45 { 46 fi[i]=i?(fi[i-1]*i%MOD):1; 47 } 48 inv[2*len]=quick(fi[2*len],MOD-2); 49 for(LL i=(2*len-1);i>=0;i--) 50 inv[i]=(i+1)*inv[i+1]%MOD; 51 // printf("~~\n"); 52 for(LL i=0;i<len;i++) 53 { 54 if(a[i]==')') 55 ge2++; 56 } 57 for(LL i=0;i<len;i++) 58 { 59 if(a[i]=='(') 60 { 61 ge1++; 62 // cout<<ge1+ge2-1<<" "<<ge1<<endl; 63 // cout<<C(ge1+ge2-1,ge1)<<endl; 64 re=(re+C(ge1+ge2-1,ge1))%MOD; 65 } 66 else 67 ge2--; 68 } 69 cout<<re<<"\n"; 70 return 0; 71 }
不过这次比赛终于没有FST,顺利上了蓝名……