文章目录
题目:Soldier and Cards
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
queue<int>s, t;
map<queue<int>, queue<int> >mp;
int main(){
int n, k1, k2;
scanf("%d", &n);
scanf("%d", &k1);
for(int i = 1; i <= k1;i++){
int v;
scanf("%d", &v);
s.push(v);
}
//if(mp[s] == t)cout<<"jkjk"<<endl;
scanf("%d", &k2);
for(int i = 1; i <= k2; i++){
int v;
scanf("%d", &v);
t.push(v);
}
mp[s] = t;
//cout<<s.size()<<" "<<t.size()<<endl;
int flag = 0;
int cn = 0;
while(s.size() != n && s.size() != 0){
int x, y;
x = s.front();
y = t.front();
s.pop(), t.pop();
if(x > y){
s.push(y);
s.push(x);
}
else {
t.push(x);
t.push(y);
}
cn++;
if(mp.count(s) && mp[s] == t){//一定要使用mp.count,因为mp映射的队列默认位空队列,所以当s之前没有出现过,并且t位空的时候使结果出现问题
flag = 1;
break;
}
mp[s] = t;
}
if(flag)printf("-1\n");
else {
printf("%d ", cn);
if(!s.size())printf("2\n");
else printf("1\n");
}
return 0;
}
Divide by three, multiply by two
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200;
#define LL unsigned long long
LL a[maxn], mark[maxn], r[maxn];
map<LL, int>vis;
int n, cn;
int dfs(LL x, int step)
{
if(step == n - 1)
{
cn = step;
for(int i = 0; i < n; i++)
{
r[i] = mark[i];
}
return 1;
}
if(x % 3 == 0 && vis[x/3])
{
mark[step] = x/3;
if(dfs(x/3, step+1))return 1;
}
if(vis[x*2])
{
mark[step] = x*2;
if(dfs(x*2, step+1)) return 1;
}
return 0;
}
int main()
{
scanf("%d", &n);
vis.clear();
for(int i = 1; i <= n; i++)
{
scanf("%llu", &a[i]);
vis[a[i]]++;
}
for(int i = 1; i <= n; i++)
{
cn = 0;
if(dfs(a[i], 0))
{
printf("%llu", a[i]);
for(int i = 0; i < cn; i++)
{
printf(" %llu", r[i]);
}
printf("\n");
}
}
return 0;
}
题目:Mahmoud and Ehab and the bipartiteness
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn = 2e5+10;
int vis[maxn], n;
int tot = 1, head[maxn], Next[maxn], to[maxn];
void add(int u, int v){
to[tot] = v;
Next[tot] = head[u];
head[u] = tot++;
}
void dfs(int x, int fa, int status){
for(int i = head[x]; i; i = Next[i]){
int v = to[i];
if(v == fa)continue;
if(status)vis[v] = 1;
else vis[v] = 2;
//cout<<v<<endl;
dfs(v, x ,!status);
}
}
int main(){
scanf("%d", &n);
tot = 1;
for(int i = 1; i < n; i++){
int u, v;
scanf("%d %d", &u, &v);
add(u, v);
add(v, u);
}
int root;
vis[1] = 1;
dfs(1,-1,0);
LL cn = 0;
for(int i = 1; i <= n; i++){
if(vis[i] == 1)cn++;
}
printf("%lld\n", (1LL)*cn*(n-cn)-n+1);
return 0;
}
题目: News Distribution
并查集
不知道用递推的方法为什么会超时,用递归的方法反而没有超时
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5+10;
int f[maxn], sz[maxn], vis[maxn];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
int Find(int x)//查询根
{
if(f[x]==x)
return x;
else
return f[x] = Find(f[x]);
}
void init(int n){
for(int i = 1; i <= n; i++){
sz[i] = 1;
f[i] = i;
}
}
int main(){
int n, m;
n = read(), m = read();
init(n);
for(int i = 1; i <= m; i++){
int k, v, pre;
k = read();
for(int j = 1; j <= k; j++){
v = read();
if(j == 1){
pre = v;
continue;
}
int xx = Find(pre), yy = Find(v);
if(xx == yy)continue;
sz[xx] += sz[yy];
f[yy] = xx;
}
}
for(int i = 1; i <= n; i++){
vis[i] = sz[Find(i)];
printf("%d ", vis[i]);
}
printf("\n");
return 0;
}