-----------------
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;
}
-----------------