CodeForces 1072 A/B/C/D - [待補]
阿新 • • 發佈:2018-10-31
連結:http://codeforces.com/contest/1072/problem
A - Golden Plate - [計算題]
#include<bits/stdc++.h> using namespace std; inline int calc(int w,int h){return (w+h-2)*2;} int w,h,k; int ans; int main() { cin>>w>>h>>k; for(;w&&h&&k;w-=4,h-=4,k--) ans+=calc(w,h); cout<<ans<<endl; }
B - Curiosity Has No Limits - [DFS]
對於常數 $C_1,C_2$ 和變數 $x,y$ 的方程組:
$\left\{ {\begin{array}{*{20}c} {C_1 = x|y} \\ {C_2 = x\& y} \\ \end{array}} \right.$
除了 $x$ 和 $y$ 之間能互換一下之外,其實解是唯一的。
因此,說是從 $1$ 到 $n$ 的深搜,其實只是 $O(n)$ 的列舉,因為當你確定了第一個數字 $t[1]$ 之後,後面的跟著都是確定的,因此只會DFS只會跑一條深度為 $n$ 的鏈。
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> pii; const int maxn=1e5+50; int n; pii a[maxn],b[maxn]; pii cho[4]; bool judge(pii a,pii b,pii x,pii y) { if((x.first|y.first)!=a.first || (x.second|y.second)!=a.second) return 0; if((x.first&y.first)!=b.first || (x.second&y.second)!=b.second) return0; return 1; } bool ok; int c[maxn]; void dfs(int d,int p) { if(ok) return; if(d==n+1) { ok=1; return; } for(int i=0;i<=3;i++) { if(judge(a[d-1],b[d-1],cho[p],cho[i])) { c[d]=i; dfs(d+1,i); } } } int main() { cho[0]=make_pair(0,0); cho[1]=make_pair(0,1); cho[2]=make_pair(1,0); cho[3]=make_pair(1,1); cin>>n; for(int i=1,k;i<n;i++) { scanf("%d",&k); a[i].first=k/2; a[i].second=k%2; } for(int i=1,k;i<n;i++) { scanf("%d",&k); b[i].first=k/2; b[i].second=k%2; } ok=0; for(int i=0;i<=3;i++) { c[1]=i; dfs(2,i); if(ok) break; } if(ok) { printf("YES\n"); for(int i=1;i<=n;i++) printf("%d ",c[i]); printf("\n"); } else printf("NO\n"); }
C - Cram Time - [暴力]
(忍不住想說,我隊友太強了,跟他組隊是我拖後腿了55555)
顯然,要放最多的數進去,肯定是放 $1 \sim n$,其中 $n$ 是滿足 $\frac{{\left( {n + 1} \right)n}}{2} \le a + b$ 的最大整數。
考慮第一天看 $a$ 的書,我們從最大的 $n$ 列舉起,遇到能塞得下的就往裡塞,這樣必然可以讓第一天的 $a$ 個小時被佔滿,
而剩下的全部放到第二天就行了,剩下的那些加起來必然不會超過 $b$ 小時。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=63300; ll a,b; ll n; bool vis[maxn]; int main() { cin>>a>>b; for(n=0;n<maxn;n++) if((n+1)*n/2<=a+b && (n+2)*(n+1)/2>a+b) break; memset(vis,0,sizeof(vis)); int cnt=0; for(int i=n;i>=1;i--) { if(a>=i) { vis[i]=1; a-=i; cnt++; } } printf("%d\n",cnt); for(int i=1;i<=n;i++) if(vis[i]) printf("%d ",i); printf("\n"); printf("%d\n",n-cnt); for(int i=1;i<=n;i++) if(!vis[i]) printf("%d ",i); printf("\n"); }
D - Minimum path - [待補]