Codeforces Round #106 (Div. 2) //缺E
-------------------------
A. Business trip
---
至少浇几个月水能使花的长度超过k。
---
#include <iostream> #include <algorithm> using namespace std; int main() { int k; int a[13]; int sum=0; int ans=-1; cin>>k; for (int i=0;i<12;i++){ cin>>a[i]; } sort(a,a+12,greater<int>()); if (k==0){ cout<<0<<endl; return 0; } for (int i=0;i<12;i++){ sum+=a[i]; if (sum>=k){ ans=i+1; break; } } cout<<ans<<endl; return 0; }-------------------------
B. Martian Clock
---
给出小时:分钟,求它可能是的进制数。
暴力枚举进制然后换算成十进制,判断是否符合条件即可。
---
#include <iostream> #include <vector> #include <cstring> #include <string> using namespace std; string s; char a[1111]; char b[1111]; int getv(char c){ if (c>='0'&&c<='9') return c-'0'; if (c>='A'&&c<='Z') return c-'A'+10; return -1; } vector<int>ans; int main() { cin>>s; int len=s.length(); int p=s.find(':'); int la=0,lb=0; for (int i=0;i<p;i++){ a[la++]=s[i]; } a[la]=0; for (int i=p+1;i<len;i++){ b[lb++]=s[i]; } b[lb]=0; int hh=0,ss=0; bool flag; for (int bt=2;bt<=200;bt++){ hh=0,ss=0; flag=true; for (int i=0;i<la;i++){ int num=getv(a[i]); if (num>=bt){ flag=false; break; } hh=hh*bt+num; } if (!flag) continue; for (int i=0;i<lb;i++){ int num=getv(b[i]); if (num>=bt){ flag=false; break; } ss=ss*bt+num; } if (!flag) continue; if (hh>=0&&hh<24&&ss>=0&&ss<60) ans.push_back(bt); } if (ans.size()==0) cout<<0<<endl; else if (ans.size()>100) cout<<-1<<endl; else{ for (int i=0;i<(int)ans.size();i++){ cout<<ans[i]<<" "; } cout<<endl; } return 0; }-------------------------
C. Division into Teams
---
将n个带权人平均分为两组要求和差小于最大权值的人。
排序,从小到大轮流分组。最大值放到较小的那一组即可。
跪求证明。
---
#include <iostream> #include <cstring> #include <algorithm> #include <vector> using namespace std; int n; struct Dat{ int v; int id; }; Dat a[111111]; bool cmp(Dat a,Dat b){ return a.v<b.v; } vector<int>ansx,ansy; int main() { cin>>n; for (int i=0;i<n;i++){ cin>>a[i].v; a[i].id=i+1; } sort(a,a+n,cmp); //for (int i=0;i<n;i++) cout<<a[i].v<<" ";cout<<endl; int sumx=0,sumy=0; for (int i=0;i<n-1;i++){ if (i&1){ ansx.push_back(a[i].id); sumx+=a[i].v; } else{ ansy.push_back(a[i].id); sumy+=a[i].v; } } if (sumx<sumy) ansx.push_back(a[n-1].id); else ansy.push_back(a[n-1].id); cout<<ansx.size()<<endl; for (int i=0;i<(int)ansx.size();i++) cout<<ansx[i]<<" ";cout<<endl; cout<<ansy.size()<<endl; for (int i=0;i<(int)ansy.size();i++) cout<<ansy[i]<<" ";cout<<endl; return 0; }-------------------------
D. Coloring Brackets
---
括号染色,给出一串匹配的括号。
满足以下条件。
每个括号只可能有三种颜色,无色红色蓝色。
任意一对匹配括号中有且仅有一个彩色括号。
相邻两个括号颜色不同。
DP
f[l][r][cl][cr]表示将区间[l,r]的括号染色,并且l的颜色为cl,r的颜色为cr的方案数。
当l与r匹配时。
若cl,cr颜色不满足条件,则方案为0。
若l,r相邻,则方案为1。
否则,方案为dp(l+1,r-1,i,j),i,j为l+1,r-1合理的配色。
当l与r不匹配时。
方案数为 dp(l,match[l],cl,i)*dp(match[l]+1,r,j,cr) ,即匹配左括号的方案数 X 剩下的括号方案数。(i,j为合理的配色)
---
#include <iostream> #include <cstring> #include <stack> using namespace std; typedef long long LL; const int MOD=1000000007; const int maxn=800; stack<int>stk; char s[maxn]; int match[maxn]; LL f[maxn][maxn][3][3]; LL ans; bool check(int i,int j){ if (i==0||j==0||i!=j) return true; return false; } LL dp(int l,int r,int cl,int cr){ LL &res=f[l][r][cl][cr]; if (res!=-1) return res; res=0; if (match[l]==r){ if ((cl==0)^(cr==0)){ if (l+1==r) return res=1; for (int i=0;i<3;i++) for (int j=0;j<3;j++) if (check(cl,i)&&check(j,cr)){ res=(res+dp(l+1,r-1,i,j))%MOD; } } } else{ for (int i=0;i<3;i++) for (int j=0;j<3;j++) if (check(i,j)){ res=(res+dp(l,match[l],cl,i)*dp(match[l]+1,r,j,cr))%MOD; } } return res; } int main() { while (cin>>(s+1)){ ans=0; while (!stk.empty()) stk.pop(); memset(match,0,sizeof(match)); memset(f,-1,sizeof(f)); int n=strlen(s+1); for (int i=1;i<=n;i++){ if (s[i]=='(') stk.push(i); else{ match[stk.top()]=i; stk.pop(); } } for (int i=0;i<3;i++) for (int j=0;j<3;j++) ans=(ans+dp(1,n,i,j))%MOD; cout<<ans<<endl; } return 0; }
-------------------------
---
---
-------------------------
---
---