一同学发来的题目:
A.
G将军有一支训练有素的军队,这个军队除开G将军外,每名士兵都有一个直接上级(可能是其他士兵,也可能是G将军)。现在G将军将接受一个特别的任务,需要派遣一部分士兵(至少一个)组成一个敢死队,为了增加敢死队队员的独立性,要求如果一名士兵在敢死队中,他的直接上级不能在敢死队中。 请问,G将军有多少种派出敢死队的方法。注意,G将军也可以作为一个士兵进入敢死队。 输入格式 输入的第一行包含一个整数n,表示包括G将军在内的军队的人数。军队的士兵从1至n编号,G将军编号为1。 接下来n-1个数,分别表示编号为2, 3, ..., n的士兵的直接上级编号,编号i的士兵的直接上级的编号小于i。 输出格式 输出一个整数,表示派出敢死队的方案数。由于数目可能很大,你只需要输出这个数除10007的余数即可。
样例输入
3
3 1 1
样例输出
4
样例说明 : 这四种方式分别是: 1. 选1; 2. 选2; 3. 选3; 4. 选2, 3。
样例输入
7
1 1 2 2 3 3
样例输出
40
数据规模与约定 对于20%的数据,n ≤ 20; 对于40%的数据,n ≤ 100; 对于100%的数据,1 ≤ n ≤ 100000。
资源约定: 峰值内存消耗 < 256M CPU消耗 < 2000ms
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define MOD 10007 #define N 100010 struct Edge { int to,next; }edge[N<<1]; int head[N],tot; int n; int dp[N][2]; //1表示取当前,0表示取儿子 void init() { tot=0; memset(head,-1,sizeof(head)); memset(dp,0,sizeof(dp)); } void add(int x,int y) { edge[tot].to=y; edge[tot].next=head[x]; head[x]=tot++; } void dfs(int u) { dp[u][0]=dp[u][1]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; dfs(v); dp[u][1]=(dp[u][1]*dp[v][0])%MOD; dp[u][0]=(dp[u][0]*(dp[v][1]+dp[v][0]))%MOD; } } int main() { while(scanf("%d",&n)!=EOF) { init(); for(int i=2;i<=n;i++) { int x; scanf("%d",&x); add(x,i); } dfs(1); printf("%d\n",(dp[1][0]+dp[1][1]-1)%MOD); } return 0; }
B、
你一定听说过“数独”游戏。 如【图1.png】,玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个同色九宫内的数字均含1-9,不重复。
数独的答案都是唯一的,所以,多个解也称为无解。
本图的数字据说是芬兰数学家花了3个月的时间设计出来的较难的题目。但对会使用计算机编程的你来说,恐怕易如反掌了。
本题的要求就是输入数独题目,程序输出数独的唯一解。我们保证所有已知数据的格式都是合法的,并且题目有唯一的解。
格式要求,输入9行,每行9个数字,0代表未知,其它数字为已知。 输出9行,每行9个数字表示数独的解。
例如: 输入(即图中题目):
005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700
程序应该输出:
145327698
839654127
672918543
496185372
218473956
753296481
367542819
984761235
521839764
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define N 9 struct node { int x,y; }s[N*N+2]; int n; bool flag; int mpt[N+1][N+1]; bool fit(int t,int k) { int i,j; for(i=0;i<N;i++) { if(mpt[s[t].x][i]==k || mpt[i][s[t].y]==k) return 0; } int x=(s[t].x/3)*3; int y=(s[t].y/3)*3; for(i=x;i<x+3;i++) { for(j=y;j<y+3;j++) { if(mpt[i][j]==k) return 0; } } return 1; } void DFS(int now) { if(now==n+1) { for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { printf("%d",mpt[i][j]); } printf("\n"); } flag=1; return; } for(int k=1;k<=N;k++) { if(!flag && fit(now,k)) { mpt[s[now].x][s[now].y]=k; DFS(now+1); mpt[s[now].x][s[now].y]=0; } } } int main() { n=0; flag=0; for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { scanf("%1d",&mpt[i][j]); if(!mpt[i][j]) { s[++n].x=i; s[n].y=j; } } } DFS(1); return 0; }