hiho编程练习赛20
模版题的世界
题目1 : 无根数变有根树
描述
给定一棵包含 N 个节点的无根树,小Hi想知道如果指定其中某个节点 K 为根,那么每个节点的父节点是谁?
输入
第一行包含一个整数 N 和 K。1 ≤ N ≤ 1000, 1 ≤ K ≤ N。
以下N-1行每行包含两个整数 a 和 b,代表ab之间存在一条边。 1 ≤ a, b ≤ N。
输入保证是一棵树。
输出
输出一行包含 N 个整数,分别代表1~N的父节点的编号。对于 K 的父节点输出0。
- 样例输入
-
5 4 1 2 3 1 4 3 5 1
- 样例输出
-
3 1 4 0 1
DFS就好啦
#include <bits/stdc++.h> using namespace std; #define N 1005 vector<int>G[N]; int f[N]; int n; void dfs(int u,int fa) { int d=G[u].size(); for(int i = 0;i<d;i++) { int v=G[u][i]; if (v!=fa){ dfs(v,f[v]=u); } } } int main() { scanf("%d",&n); int root; scanf("%d",&root); for(int i=0;i<n-1;i++){ int u,v; scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } f[root]=0; dfs(root,-1); printf("%d",f[1]); for(int i=2;i<=n;i++) printf(" %d",f[i]); return 0; }
题目2 : SCI表示法
时间限制:10000ms单点时限:1000ms内存限制:256MB描述
每一个正整数 N 都能表示成若干个连续正整数的和,例如10可以表示成1+2+3+4,15可以表示成4+5+6,8可以表示成8本身。我们称这种表示方法为SCI(Sum of Consecutive Integers)表示法。
小Hi发现一个整数可能有很多种SCI表示,例如15可以表示成1+2+3+4+5,4+5+6,7+8以及15本身。小Hi想知道N的所有SCI表示中,最多能包含多少个连续正整数。例如1+2+3+4+5是15包含正整数最多的表示。
输入
第一行一个整数 T,代表测试数据的组数。
以下 T 行每行一个正整数N。
对于30%的数据,1 ≤ N ≤ 1000
对于80%的数据,1 ≤ N ≤ 100000
对于100%的数据,1 ≤ T ≤ 10,1 ≤ N ≤ 1000000000
输出
对于每组数据输出N的SCI表示最多能包含多少个整数。
- 样例输入
-
2 15 8
- 样例输出
-
5 1
更经典的模版题,直接枚举个数,利用奇偶性就好了,如果让求全部方案感觉还是一道不错的题
#include<bits/stdc++.h> using namespace std; int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); n=2*n; for(int z=sqrt(n+0.5);z>0;z--){ if(n%z==0){ if(n/z%2==0&&z%2==0) continue; else {printf("%d\n",z);break;} } } } return 0; }
题目4:小Hi和小Ho的对弈游戏
时间限制:10000ms单点时限:1000ms内存限制:256MB描述
小Hi和小Ho经常一起结对编程,他们通过各种对弈游戏决定谁担任Driver谁担任Observer。
今天他们的对弈是在一棵有根树 T 上进行的。小Hi和小Ho轮流进行删除操作,其中小Hi先手。
游戏的规则是:每次删除,小Hi或小Ho都可以选择一个非根节点,将以该节点为根的子树从 T 中删除。如果删除之后 T 只剩下一个根节点,则该次操作者胜利。
机智的小Ho认为规则对自己不利,于是他提出了一个补充规则:在小Hi第一次删除之前,小Ho可以选择是否删除根节点。如果他选择删除根节点,则原本的有根树 T 会分裂成一个森林。之后每次删除,小Hi或小Ho都可以选择一个非根节点(不是森林中任何一棵树的根),将以该节点为根的子树删除。如果删除之后森林中只剩下根节点,则该次操作者胜利。
小Hi和小Ho都是睿智的玩家,他们总是会选择最优的方案以获得胜利。
给定初始的有根树T,输出两个布尔值,分别代表小Ho在不删除和删除根节点时,先手的小Hi是否有必胜策略。0代表没有,1代表有。
输入
第一行包含一个整数 Q,代表测试数据的组数。1 ≤ Q ≤ 10
对于每组数据,第一行包含一个正整数 n,代表树T的节点个数。1 ≤ n ≤ 100000
接下来n-1行,每行包含两个整数 x 和 y,代表 x 是 y 的父节点。保证输入是一棵树,节点编号1-n。
输出
输出一个长度为2Q的01串,代表答案。
- 样例输入
-
2 5 2 5 5 4 2 3 1 2 7 4 7 2 6 1 5 3 4 1 3 1 2
- 样例输出
-
1101
树上博弈,遍历树,求异或和
#include <bits/stdc++.h> using namespace std; const int N=100010; vector<int>vec[N]; int vis[N],sg[N]; void dfs(int u,int fa) { sg[u]=0; for(int i=0; i<vec[u].size(); i++) { if(vec[u][i]!=fa) { dfs(vec[u][i],u); sg[u]^=(1+sg[vec[u][i]]); } } } int main() { string s; int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); for(int i=1; i<=n; i++) { vec[i].clear(); vis[i]=0; } for(int i=1; i<n; i++) { int a,b; scanf("%d%d",&a,&b); vec[a].push_back(b); vis[b]=1; } int root; for(int i=1; i<=n; i++) if(!vis[i]) { root=i; break; } dfs(root,0); if(sg[root])s+='1'; else s+='0'; int f=0; for(int i=0; i<vec[root].size(); i++)f^=sg[vec[root][i]]; if(f)s+='1'; else s+='0'; } cout<<s; return 0; }
本文来自博客园,作者:暴力都不会的蒟蒻,转载请注明原文链接:https://www.cnblogs.com/BobHuang/p/7259095.html