您的位置:首页 > 其它

蓝桥杯第五届题目求解

2018-03-03 18:00 309 查看

第四题

题目

今有7对数字:两个1,两个2,两个3,…两个7,把它们排成一行。

要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是一个符合要求的排列:

17126425374635

当然,如果把它倒过来,也是符合要求的。

请你找出另一种符合要求的排列法,并且这个排列法是以74开头的。

注意:只填写这个14位的整数,不能填写任何多余的内容,比如说明注释等。

代码

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <stdio.h>
using namespace std;

int res[14];  // 最终的排序结果
int t[7]; // 7个数的使用次数

void dfs( int x )
{
if( x == 14 )
{
for(int i=0;i<14;i++)
printf("%d", res[i]);
printf("\n");
return;
}
for(int i=0;i<7;i++)
{
if( t[i] <= 0 )
continue;
if( t[i] == 2 )
{
t[i]--;
res[x] = i+1;
dfs( x+1 );
t[i]++;
}
else if(t[i] == 1)
{
if( i+2<=x && i+1 == res[x-i-2] )
{
t[i]--;
res[x] = i+1;
dfs( x+1 );
t[i]++;
}
}
}
}

int main()
{
for(int i=0;i<7;i++)
t[i] = 2; // 初始2次
res[0] = 7;
res[1] = 4;
t[3] = 1;
t[6] = 1;
dfs( 2 );
return 0;
}


* 注:只用DFS求解即可。

第六题

题目

你一定听说过“数独”游戏。

如【图1.png】,玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个同色九宫内的数字均含1-9,不重复。

数独的答案都是唯一的,所以,多个解也称为无解。

本图的数字据说是芬兰数学家花了3个月的时间设计出来的较难的题目。但对会使用计算机编程的你来说,恐怕易如反掌了。

本题的要求就是输入数独题目,程序输出数独的唯一解。我们保证所有已知数据的格式都是合法的,并且题目有唯一的解。

格式要求:

输入9行,每行9个数字,0代表未知,其它数字为已知。

输出9行,每行9个数字表示数独的解。

代码

使用DFS就可以直接求解

src.txt中的内容是

005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700


参考链接:http://blog.csdn.net/u013231041/article/details/44596415

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <stdio.h>
using namespace std;
int a[9][9];

// 判断行与列是否为重复
bool noRepeatRowCol(int r, int c, int val)
{
for(int i=0;i<9;i++)
if( a[i][c] == val )
return false;
for(int i=0;i<9;i++)
if( a[r][i] == val )
return false;
return true;
}

// 判断一个小的3X3方格中是否重复
bool noRepeatBox(int r, int c, int val)
{
int r1 = r/3, c1=c/3;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if( a[r1*3+i][c1*3+j] == val )
return false;
}
}
return true;
}

// 输出九宫格的信息
void print()
{
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
cout << a[i][j];
cout << endl;
}
}

void dfs(int r, int c)
{
if( r >= 9 )
{
print();
return;
}

if( a[r][c] == 0 )
{
for(int i=1;i<=9;i++)
{
if( noRepeatRowCol(r,c,i) && noRepeatBox(r,c,i) )
{
a[r][c] = i;
dfs( r+(c+1)/9, (c+1)%9 );
a[r][c] = 0;
}
}
}
else
{
dfs( r+(c+1)/9, (c+1)%9 );
}
}

int main()
{
char s[10][10];
FILE *fp = fopen("src.txt","r");
for(int i=0;i<9;i++)
{
fscanf(fp,"%s",&s[i]);
}
fclose( fp );
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
a[i][j] = s[i][j] - 48;

dfs(0,0);

return 0;
}


第七题

题目

G将军有一支训练有素的军队,这个军队除开G将军外,每名士兵都有一个直接上级(可能是其他士兵,也可能是G将军)。现在G将军将接受一个特别的任务,需要派遣一部分士兵(至少一个)组成一个敢死队,为了增加敢死队队员的独立性,要求如果一名士兵在敢死队中,他的直接上级不能在敢死队中。

请问,G将军有多少种派出敢死队的方法。注意,G将军也可以作为一个士兵进入敢死队。

输入格式

输入的第一行包含一个整数n,表示包括G将军在内的军队的人数。军队的士兵从1至n编号,G将军编号为1。

接下来n-1个数,分别表示编号为2, 3, …, n的士兵的直接上级编号,编号i的士兵的直接上级的编号小于i。

输出格式

输出一个整数,表示派出敢死队的方案数。由于数目可能很大,你只需要输出这个数除10007的余数即可。

样例输入1

3

1 1

样例输出1

4

样例说明

这四种方式分别是:

1. 选1;

2. 选2;

3. 选3;

4. 选2, 3。

样例输入2

7

1 1 2 2 3 3

样例输出2

40

数据规模与约定

对于20%的数据,n ≤ 20;

对于40%的数据,n ≤ 100;

对于100%的数据,1 ≤ n ≤ 100000。

资源约定:

峰值内存消耗 < 256M

CPU消耗 < 2000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0

注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。

注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

代码

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <stdio.h>
using namespace std;

int N;

// a[i]=n表示士兵i的上级为n
int a[100005];
// 标记位,判断士兵i是否在当前的队伍中
bool isin[100005];

int sum = 0;

bool tmp = false;

void dfs(int n)
{
if( n > N )
return;

tmp = true;
for(int i=1;i<n;i++)
{
if( isin[i] && (a[i]==n || a
==i) )
{
tmp = false;
break;
}
}
// 下标为n的士兵可以插入到当前敢死队中,与之前的队伍不冲突
if( tmp )
{
sum = (sum+1) % 10007;
isin
= true;
dfs( n+1 );
isin
= false;
}
// 不加入当前士兵是另一种方法
dfs( n+1 );

}

int main()
{
scanf("%d", &N);
for(int i=2;i<=N;i++)
scanf("%d", &a[i]);
a[1] = -1; // 将军没有上级

for(int i=1;i<N;i++)
isin[i] = false;
dfs( 1 );
cout << sum << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  蓝桥杯 DFS 九宫格