题目目录:H F
H题 War of Inazuma (Easy Version)
题目大意:在n维空间有一个n维超立方体,顶点编号从0-2^n-1,定义二进制表示只有一位不同的数字相邻(如0和1,2,4相邻,和3,5,6不相邻)。现在有两个阵营,分别用0和1表示,要求一个队伍相邻的友军不能超过根号n向上取整的个数。输出一串01串表示0-2^n-1编号上的阵营。
思路:分析n==1,n==2,n==3,n==4的情况,合理推测,在n维空间的超立方体顶点有n个相邻的点,由于题目要求相邻的友军不超过根号n向上取整的个数,本人的思路是让相邻的全为敌军。分析发现,和一个点相邻的各点都不会相邻,而且n维空间的01字符串是n-1维的01字符串本身接上取反得到的字符串。取反操作可用^1实现。
#include <bits/stdc++.h> using namespace std; int main(){ vector<int> vt; int n; cin>>n; vt.clear(); vt.push_back(0); vt.push_back(1); for(int j=1;j<=n;j++) for(int i=0;i<pow(2,j);i++) vt.push_back(vt[i]^1); for(int i=0;i<pow(2,n);i++) cout<<vt[i]; return 0; }
F题 Train Wreck
题目大意:有一个类似于栈的火车通道,即按照后进先出的规则。给出颜色不全相同的火车车厢,管理员要将这些车厢按照给定的规则推入和推出通道。要求每次形成的火车排列要与之前出现过的每种情况不同。输出一种符合条件的解决方案。
思路:栈操作其实可以看做树。每一次推出前形成的火车序列可以看做树的链。只需要每个树的结点的子节点各不相同,就可以保证有符合条件的解决方案。用数组储存每种颜色对应的车厢个数,用vector储存每个结点对应的子节点,并给子节点赋不同的颜色即可。
#include <bits/stdc++.h> using namespace std; const int N=2e6+5; char s[N]; int a[N],cnt[N],last[N],ans[N]; vector<int> G[N]; int n; priority_queue<pair<int, int> > q; int main(){ cin>>n; cin>>s+1; int dep=0,tot=0; //创建一棵括号序列树 for(int i=1;i<=2*n;i++){ if(s[i]=='('){ dep++;//层数增加 G[last[dep-1]].push_back(++tot); last[dep]=i;//从上一层回到下一层,开了一个新的子树,所以用i开一个新的G[i]储存它子结点 } else dep--; } for(int i=1;i<=n;i++){ int x; cin>>x; cnt[x]++; }//记录车的颜色及对应的量数 for(int i=1;i<=n;i++) if(cnt[i]) q.push({cnt[i],i}); for (int i=0;i<=2*n;i++){ if(G[i].size()>0){ if(q.size()<G[i].size()){ cout<<"NO"<<endl; return 0; } vector<int> v;//用以减少循环次数 for(int it=0;it<G[i].size();it++){ int id=q.top().second;//颜色 ans[G[i][it]]=id;//it是推进的第it辆车 cnt[id]--;//个数 v.push_back(id); q.pop(); } for(int it=0;it<v.size();it++) if(cnt[v[it]]) q.push({cnt[v[it]],v[it]}); } } cout<<"YES"<<endl; for(int i=1;i<=n;i++) cout<<ans[i]<<" "; return 0; }