Usaco Training Section 4.3 Letter Game
阿新 • • 發佈:2018-11-12
a~z各賦一個數值(自己看圖),給你一個字典(40000個單詞),再給你一些字母,從中選幾個組成一個或兩個單詞,使和最大。
最直接的想法就是n^2列舉單詞,但n=40000,肯定要炸。
然後我就想到可以構造,從這些字母中選幾個,再把選出的字母分成兩堆,全排列一下。這個看起來挺靠譜的,因為最多隻有7個字母。
於是我就開始暴力取、分、排……一下搞了100多行,一測,把樣例水過了。一交,wa……原來答案排序時沒有特判空串,改了就過了,竟然跑得還挺快的!
#include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define inf 2147483647 #define mp make_pair #define pii pair<int,int> #define pb push_back #define pss pair<string,string> using namespace std; inline int read(){ int x=0;char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x; } map<string,bool> m; int tim[30],b[10],c[10],ti[30]; char a[10],a2[10],a1[10]; int sc[27]={0,2,5,4,4,1,6,5,5,1,7,6,3,5,2,3,5,7,2,1,2,4,6,6,7,5,7}; int main() { ios::sync_with_stdio(false); freopen("lgame.in","r",stdin); freopen("lgame.out","w",stdout); string s; cin>>s; int n=s.length(); s=' '+s; fclose(stdin); for(int i=1;i<=n;++i) ++tim[s[i]-96]; freopen("lgame.dict","r",stdin); string str; cin>>str; while(str!="."){ m[str]=1; cin>>str; } for(int i=1;i<=n;++i) b[i]=0; int maxv=0; set<pss> ans; while(b[0]==0){ int t=0; for(int i=1;i<=n;++i) if(b[i]==1) a[++t]=s[i]; for(int i=0;i<=t;++i) c[i]=0; while(c[0]==0){ int t1=0,t2=0; for(int i=1;i<=t;++i) if(c[i]) a1[++t1]=a[i]; else a2[++t2]=a[i]; sort(a1+1,a1+t1+1); do{ string s1=""; for(int i=1;i<=t1;++i) s1+=a1[i]; if(s1!=""&&!m[s1]) continue; sort(a2+1,a2+t2+1); do{ string s2=""; for(int i=1;i<=t2;++i) s2+=a2[i]; if(s2!=""&&!m[s2]) continue; if(s1>s2) continue; for(int i=1;i<=26;++i) ti[i]=0; bool f=1; int sum=0; for(int i=1;i<=t1;++i){ int x=a1[i]-96; ++ti[x]; if(ti[x]>tim[x]){f=0;break;} sum+=sc[x]; } if(!f) continue; for(int i=1;i<=t2;++i){ int x=a2[i]-96; ++ti[x]; if(ti[x]>tim[x]){f=0;break;} sum+=sc[x]; } if(f){ if(sum>maxv){ maxv=sum; ans.clear(); if(s1=="") swap(s1,s2); ans.insert(mp(s1,s2)); } else if(sum==maxv){ if(s1=="") swap(s1,s2); ans.insert(mp(s1,s2)); } } }while(next_permutation(a2+1,a2+t2+1)); }while(next_permutation(a1+1,a1+t1+1)); int x=t; while(c[x]==1) c[x]=0,--x; c[x]=1; } int x=n; while(b[x]==1) b[x]=0,--x; b[x]=1; } cout<<maxv<<'\n'; while(!ans.empty()){ pss tmp=*ans.begin();ans.erase(ans.begin()); if(tmp.second=="") cout<<tmp.first<<'\n'; else cout<<tmp.first<<' '<<tmp.second<<'\n'; } return 0; }
4.3刷完了,繼續加油!