Codeforces Round #197 (Div. 2)
-----------------
A. Helpful Maths
----
将一个由+和123组成的式子从小到大排序...
----
#include <iostream> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int maxn=1111; char s[maxn]; vector<int>vc; int main() { vc.clear(); cin>>s; int len=strlen(s); for (int i=0;i<len;i++) { if (s[i]>='1'&&s[i]<='3') { vc.push_back(s[i]-'0'); } } sort(vc.begin(),vc.end()); cout<<vc[0]; for (int i=1;i<(int)vc.size();i++) { cout<<"+"<<vc[i]; } cout<<endl; return 0; }-----------------
B. Xenia and Ringroad
----
1..n地点环形排列,只能顺时针前进,给出m个目标地点,问按顺序转一遍需要经过几个地点。
----
#include <iostream> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int maxn=1111; char s[maxn]; vector<int>vc; int main() { vc.clear(); cin>>s; int len=strlen(s); for (int i=0;i<len;i++) { if (s[i]>='1'&&s[i]<='3') { vc.push_back(s[i]-'0'); } } sort(vc.begin(),vc.end()); cout<<vc[0]; for (int i=1;i<(int)vc.size();i++) { cout<<"+"<<vc[i]; } cout<<endl; return 0; }
-----------------
C. Xenia and Weights
----
有质量在1...10之间的一些砝码,每个质量都有无数个,按照一定规则放在天平上。
左->右->左->右.....
假如第i步放了质量为x的砝码,则第i+1步不能放x。
第i+1步的天平倾斜方向与第i步不同。不能平衡。
----
设天平两端质量差为w。
则0<w<10,第x次放的砝码质量为t且t>w。
第x+1次两端质量差为t-w。
搜索、DP解决。
----
vector<int>ans; char s[13]; int m; bool dfs(int x,int w){ if (x>=m){ return true; } for (int i=w+1;i<=10;i++){ if (s[i]=='1'){ if (sz(ans)==0||(sz(ans)>0&&ans[x-1]!=i)){ ans.push_back(i); if (dfs(x+1,i-w)) return true; ans.pop_back(); } } } return false; } int main() { ans.clear(); cin>>(s+1)>>m; if (dfs(0,0)){ cout<<"YES"<<endl; REP(i,sz(ans)) cout<<ans[i]<<" "; cout<<endl; } else{ cout<<"NO"<<endl; } return 0; }-----------------
D. Xenia and Bit Operations
----
给出2^n个数,相邻的两两做OR操作,得到的新数列两两做XOR,新数列再做OR...如此重复最终得到一个值V。
给出m个操作。每次将原数列的第p项的值改为b,并输出V。
----
线段树维护单点更新,对每一层交替用OR和XOR维护。输出根节点的值即可。
----
int num[N]; struct Tree{ int l,r; int v; int d; }tree[N*4]; void push_up(int root){ if (tree[root].d&1) tree[root].v=tree[root<<1].v|tree[root<<1|1].v; else tree[root].v=tree[root<<1].v^tree[root<<1|1].v; } void build(int root,int l,int r){ tree[root].l=l; tree[root].r=r; if(tree[root].l==tree[root].r){ tree[root].v=num[l]; tree[root].d=0; return; } int mid=(l+r)/2; build(root<<1,l,mid); build(root<<1|1,mid+1,r); tree[root].d=tree[root<<1].d+1; push_up(root); } void update(int root,int pos,int val){ if(tree[root].l==tree[root].r){ tree[root].v=val; return; } int mid=(tree[root].l+tree[root].r)/2; if(pos<=mid) update(root<<1,pos,val); else update(root<<1|1,pos,val); push_up(root); } int query(){ return tree[1].v; } int main() { int n,m,mn; int p,b; cin>>n>>m; mn=int(pow(2,n)); for (int i=1;i<=mn;i++) cin>>num[i]; build(1,1,mn); while (m--){ cin>>p>>b; update(1,p,b); cout<<query()<<endl; } return 0; }
-----------------
E. Three Swaps
----
有1...n匹马,有操作(l,r)可翻转区间[l,r]。
最多操作三次,给出最终结果,要求找到一个可能的操作序列。
----
由于数量极少,可以直接搜索。
----
const int maxn=1111; int n; int a[maxn]; vector< pair<int,int> > ans; int left(){ for (int i=1;i<=n;i++){ if (a[i]!=i) return i; } return 0; } int right(){ for (int i=n;i>=1;i--){ if (a[i]!=i) return i; } return 0; } int getX(int x){ for (int i=1;i<=n;i++){ if (x==a[i]) return i; } return 0; } bool dfs(int x){ int l,r; l=left(); if (l==0) return true; if (x>=3) return false; r=getX(l); reverse(a+l,a+r+1); if (dfs(x+1)){ ans.push_back(make_pair(l,r)); return true; } reverse(a+l,a+r+1); r=right(); l=getX(r); reverse(a+l,a+r+1); if (dfs(x+1)){ ans.push_back(make_pair(l,r)); return true; } reverse(a+l,a+r+1); return false; } int main() { ans.clear(); cin>>n; REP_1(i,n) cin>>a[i]; dfs(0); cout<<ans.size()<<endl; REP(i,sz(ans)){ cout<<ans[i].first<<" "<<ans[i].second<<endl; } return 0; }
-----------------