01 The Country List
暴力for过去。
02 Polygon
计算几何模板。
03 The collector’s puzzle
因为盒子能使用多次,排序后取一个最接近的。
#include <bits/stdc++.h> using namespace std; #define ll long long int a[100010]; int b[100010]; int min3(int a,int b,int c){ if(a<b){ if(a<c)return a; return c; }else{ if(b<c)return b; return c; } } int main(){ int n,m; while(cin>>n>>m){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<=m;i++){ scanf("%d",&b[i]); } sort(a+1,a+n+1); sort(b+1,b+m+1); b[0]=-1e9; b[m+1]=1e9; b[m+2]=1e9; int pos = 1; int ans = 0; for(int i=1;i<=n;i++){ while(b[pos]<a[i] && pos<=m){ pos++; } ans+=min3(abs(a[i]-b[pos-1]),abs(a[i]-b[pos]),abs(a[i]-b[pos+1])); } cout<<ans<<endl; } return 0; }
04 Happy Value
最大生成树,拿MST改改就好。
05 Bitwise Equations
贪心。二进制表示下,取n为0的位,填上k。
#include <bits/stdc++.h> using namespace std; #define ll long long char names[111][22]; int main(){ int t; cin>>t; while(t--){ ll n,k; cin>>n>>k; ll ans = 0; ll tmp = 1; while(k){ while(n&tmp){ tmp<<=1; } if(k&1)ans|=tmp; tmp<<=1; k>>=1; } cout<<ans<<endl; } return 0; }
06 01 Matrix
统计两个方向的前缀和(左,上),然后小到大推出来。
#include <bits/stdc++.h> using namespace std; #define ll long long char mat[1010][1010]; int L[1010][1010]; int U[1010][1010]; int MAX[1010][1010]; int cnt[1010]; int ans[1010]; int main(){ int t; cin>>t; while(t--){ memset(cnt,0,sizeof(cnt)); memset(ans,0,sizeof(ans)); int n; int m; cin>>n>>m; for(int i=0;i<n;i++){ scanf("%s",mat[i]); for(int j=0;j<n;j++){ mat[i][j]-='0'; } } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(mat[i][j]){ L[i][j]=1; U[i][j]=1; MAX[i][j]=1; if(i>0){ U[i][j]=U[i-1][j]+1; } if(j>0){ L[i][j]=L[i][j-1]+1; } if(i>0&&j>0){ int tmp=min(L[i][j],U[i][j]); MAX[i][j]=min(tmp,MAX[i-1][j-1]+1); } }else{ L[i][j]=0; U[i][j]=0; MAX[i][j]=0; } } } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(MAX[i][j])cnt[MAX[i][j]]++; } } for(int i=n;i>0;i--){ cnt[i]+=cnt[i+1]; } for(int i=1;i<=m;i++){ int q; scanf("%d",&q); printf("%d\n",cnt[q]); } } return 0; }
07 Pick Game
看完题想都没想写了个miniMax+alapha-beta pruning,结果无限T,都是PKU游戏大赛害的。其实这个题是可以用dp做的。需要把状态编码一下,也就是哪些格子被拿了哪些没有,然后就是状态的范围太大要哈希。
#include <bits/stdc++.h> using namespace std; #define ll long long const int INF = 1e9; int v[9][9]; int n,m; int tot; int enCode(){ int p=1; int res=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(v[i][j]){ res|=p; } p<<=1; } } return res; } bool canPick(int nn,int mm){ int cnt=0; if(!v[nn-1][mm])cnt++; if(!v[nn][mm-1])cnt++; if(!v[nn+1][mm])cnt++; if(!v[nn][mm+1])cnt++; return cnt>=2; } const int mod = 1000007; int head[mod+1]; int pre[mod*4]; int dp[mod*4]; int val[mod*4]; int cnt=0; int find(int x){ int xx=x%mod; for(int i=head[xx];~i;i=pre[i]){ if(val[i]==x)return dp[i]; } return -1; } void insert(int x,int data){ int xx=x%mod; pre[cnt]=head[xx]; head[xx]=cnt; val[cnt]=x; dp[cnt]=data; cnt++; } int ab(int dep){ if(dep>tot)return 0; int code = enCode(); if(find(code)!=-1){ return find(code); } int res; if(dep&1){ res=-INF; }else{ res=INF; } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(v[i][j] && canPick(i,j)){ //make int tmp=v[i][j]; v[i][j]=0; // if(dep&1){ //me res = max(res, ab(dep+1) + tmp); }else{ //op res = min(res, ab(dep+1) - tmp); } //unmake v[i][j]=tmp; } // } } insert(code,res); return res; } int main(){ int t; cin>>t; while(t--){ memset(v,0,sizeof(v)); memset(dp,0,sizeof(dp)); memset(head,-1,sizeof(head)); cnt=0; cin>>n>>m; tot=n*m; int sum = 0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>v[i][j]; sum+=v[i][j]; } } int ans = ab(1); cout<<(sum-ans)/2+ans<<endl; } return 0; }
08 Study Words
模拟。恰当利用STL。
#include <bits/stdc++.h> using namespace std; #define ll long long const string os="<oldwords>"; const string ot="</oldwords>"; const string as="<article>"; const string at="</article>"; map<string,int> mp; set<string> dic; void fun(string tmp){ string realStr=""; int len = tmp.size(); for(int i=0;i<len;i++){ if(tmp[i]>='A' && tmp[i]<='Z'){ tmp[i]+=32; } if(tmp[i]>='a' && tmp[i]<='z'){ realStr+=tmp[i]; }else{ if(realStr.size() && !dic.count(realStr)){ mp[realStr]++; }realStr=""; } } if(realStr.size() && !dic.count(realStr)){ mp[realStr]++; realStr=""; } } set<pair<int,string> > ans; int main(){ int t; cin>>t; while(t--){ dic.clear(); mp.clear(); string tmp; while(cin>>tmp){ if(tmp==os)continue; if(tmp==ot)break; for(int i=0;i<tmp.size();i++){ if(tmp[i]>='A' && tmp[i]<='Z'){ tmp[i]+=32; } } dic.insert(tmp); } while(cin>>tmp){ if(tmp==as)continue; if(tmp==at)break; fun(tmp); } ans.clear(); map<string,int>::iterator it; for(it=mp.begin();it!=mp.end();it++){ ans.insert(make_pair(-it->second,it->first)); } int cnt = 10; set<pair<int,string> >::iterator it2; for(it2=ans.begin();it2!=ans.end();it2++){ cnt--; cout<< (*it2).second<<endl; if(!cnt)break; } cout<<endl; } return 0; }
09 The Magic Tower
模拟。
总的来说,题目都是入门级的,只有07有点难。