Codeforces Round 313(div1)
阿新 • • 發佈:2017-06-28
補全 print 依據 ng- 部分 代碼 cst force else
A題:
題目大意:
給出內角全為120度的六邊形的六條邊的邊長,求由多少邊長為1的等邊三角形構成。
解題思路:
將六邊形補全為一個大的等邊三角形,則大的等邊三角形的邊長為六邊形的相鄰三邊之和,接著減去補的部分。
補的部分是三個邊長為認識3個不相鄰的六邊形邊長的長度構成的等邊三角形,邊長為a的等邊三角形,由a*a個邊
長為1的小三角形構成。
代碼:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int main() { int a[10]; for(int i=0;i<6;i++) { scanf("%d",&a[i]); } long long cur=a[0]+a[1]+a[2]; long long ans=cur*cur-a[0]*a[0]-a[2]*a[2]-a[4]*a[4]; cout<<ans<<endl; return 0; }
B. Equivalent Strings
題目大意:
依據給定的規則推斷字符串相等。
解題思路:
依照題意遞歸寫就可。
代碼:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn=200000+1000; char s1[maxn]; char s2[maxn]; int judge(int st1,int en1,int st2,int en2) { int sign=0; for(int i=st1,j=st2;i<=en1;i++,j++) { if(s1[i]!=s2[j]) { sign=1; break; } } if(sign==0) return 1; else { if((en1-st1+1)%2==0) { int mid1=st1+(en1-st1+1)/2-1; int mid2=st2+(en2-st2+1)/2-1; if(judge(st1,mid1,st2,mid2)&&judge(mid1+1,en1,mid2+1,en2)) return 1; if(judge(st1,mid1,mid2+1,en2)&&judge(mid1+1,en1,st2,mid2)) return 1; } } return 0; } int main() { int len1,len2; scanf("%s%s",s1,s2); len1=strlen(s1); len2=strlen(s2); if(len1!=len2) cout<<"NO\n"<<endl; else { int sign; sign=judge(0,len1-1,0,len1-1); if(sign) printf("YES\n"); else printf("NO\n"); } return 0; }
C. Gerald and Giant Chess
題目大意:
給定h*w的格子,n個不可走的點。從(1,1)到(h,w)點。每次僅僅能向下或者向右。求有多少種走法?
解題思路:
首先先不考慮不可走的點,有C(h+w-2,h-1)種走法,一共走h+w-2步,向下的有h-1步。
接著考慮當中的不可走的
點,對於一個不可走的點(x,y)。它走到這個的點的走法是dp[i],它少走的是dp[i]*C(h-x,w-y,h-x),於是把每一個不可走
的點當為終點。能夠求出全部的走法數。
代碼:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int h,w,n; const int maxn=200000+100; const int mod=1000000000+7; long long c[maxn]; long long inv[maxn]; long long dp[5000]; struct node { int x; int y; }a[10000]; long long pow_mod(long long a,int b)//矩陣高速冪 { long long ans=1; while(b) { if(b&1) ans=(ans*a)%mod; a=(a*a)%mod; b=b/2; } return ans; } long long com(int x,int y)//求組合數C(x,y) { return ((c[x]*inv[y])%mod*inv[x-y])%mod; } bool cmp(node u,node v) { if(u.x==v.x) return u.y<v.y; return u.x<v.x; } int main() { scanf("%d%d%d",&h,&w,&n); for(int i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y); sort(a,a+n,cmp); long long ans=0; c[0]=1; for(int i=1;i<maxn;i++) c[i]=c[i-1]*i%mod; inv[0]=1; for(int i=1;i<maxn;i++) inv[i]=pow_mod(c[i],mod-2);//費馬小定理求逆。a^(p-2)=a^(-1) ans=com(h+w-2,h-1); for(int i=0;i<n;i++) { dp[i]=com(a[i].x+a[i].y-2,a[i].x-1); for(int j=0;j<i;j++)//求過第i個點的方法數 { if(a[j].x<=a[i].x&&a[j].y<=a[i].y)//推斷能否夠到達i點 { dp[i]-=(dp[j]*com(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x))%mod; dp[i]=(dp[i]+mod)%mod; } } ans=(ans-(dp[i]*com(h+w-a[i].x-a[i].y,h-a[i].x))%mod+mod)%mod; } cout<<ans<<endl; return 0; }
Codeforces Round 313(div1)