2014 【第五届蓝桥杯校内选拔赛】 C/C++ B组

目录html

第一题ios

第二题编程

第三题函数

第四题spa

第五题操作系统

第六题.net

第七题设计


 

第一题


输入一个字符串,求它包含多少个单词。单词间以一个或者多个空格分开。
第一个单词前,最后一个单词后也可能有0到多个空格。
好比:" abc    xyz" 包含两个单词,"ab   c   xyz    "  包含3个单词。调试

以下的程序解决了这个问题,请填写划线部分缺失的代码。code

注意:只填写划线部分的代码,不要填写任何多余的内容。好比已经存在的小括号,注释或说明文字等。

int get_word_num(char* buf)
{
	int n = 0;   
	int tag = 1; 
	char* p = buf;
	
	for(;*p!=0 && *p!=13 && *p!=10;p++){
		if(*p==' ' && tag==0) tag=1;
		if( _____________________ ) { n++; tag=0; }   //填空
	}
	
	return n;
}

int main()
{
	char buf[1000];
	fgets(buf,1000,stdin);
	
	printf("%d\n", get_word_num(buf));
	return 0;
}
//答案:
tag == 1

第二题

 
1/1 + 1/2 + 1/3 + 1/4 + ... 在数学上称为调和级数。

它是发散的,也就是说,只要加上足够多的项,就能够获得任意大的数字。

可是,它发散的很慢:

前1项和达到 1.0
前4项和才超过 2.0
前83项的和才超过 5.0

那么,请你计算一下,要加多少项,才能使得和达到或超过 15.0 呢?

请填写这个整数。

注意:只须要填写一个整数,不要填写任何多余的内容。好比说明文字。
 

#include <iostream>
using namespace std;

int main()
{
    int k = 1 ;
    double sum = 0;
    while (sum < 15.0)
    {
        sum += 1.0/k++ ;
    }
    cout << k-1;
    system("pause");
	return 0;
}
//答案:1835421

第三题


若是x的x次幂结果为10(参见【图1.png】),你能计算出x的近似值吗?

显然,这个值是介于2和3之间的一个数字。

请把x的值计算到小数后6位(四舍五入),并填写这个小数值。

注意:只填写一个小数,不要写任何多余的符号或说明。

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
 
int main()
{
    for (double x = 2; x <= 3 ; x+=0.00000001)
    {
        if(fabs(pow(x,x) - 10 )< 0.000001)
            cout << fixed << setprecision(6) << x << endl;
    }
    
    system("pause");
}

 

第四题


今有7对数字:两个1,两个2,两个3,...两个7,把它们排成一行。
要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。以下就是一个符合要求的排列:

17126425374635

固然,若是把它倒过来,也是符合要求的。

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

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

方法(1):暴力 

#include <iostream>
#include <algorithm>
using namespace std;
 
int main()
{
    char s[] = "74112233455667";
    do
    {
        int p,q;
        bool flag = true;
       for (char i = '1'; i <= '7'; i++)
        {
            for(int j = 0; j < 14; j++)    //正序找
                if(s[j] == i)
                {
                    p = j;
                    break;
                }
 
            for (int j = 13; j >= 0; j--)    //反序找
                if(s[j] == i)
                {
                    q = j;
                    break;
                }
 
            if(q - p != i-48+1)    //看相同数字相间 有多少数字
            {
                flag =false;
                break;
            }
        }
       if(flag)
            cout << s << endl;
        
    } while(next_permutation(s+2,s+14));
    
			
    system("pause");
}

 方法(2):dfs

#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <iterator>
using namespace std;
int a[20];
void dfs(int t)
{
    if(t == 4)
        dfs(t + 1);
    if(t > 6)
    {
        copy(a,a+14, ostream_iterator<int>(cout));
    }    
    for (int i = 2; i < 14; i++)
    {
        if ( (i+t+1) < 14 && a[i] == 0 && a[i+t+1] == 0)
        {
            a[i] = a[i+t+1] = t;
            dfs(t + 1);
            a[i] = a[i+t+1] = 0;
        }
    }
    
}
int main()
{
    a[0] = a[8] = 7;
    a[1] = a[6] = 4;
    dfs(1);
 
    system("pause");
}

第五题

 
  勾股定理,西方称为毕达哥拉斯定理,它所对应的三角形如今称为:直角三角形。

  已知直角三角形的斜边是某个整数,而且要求另外两条边也必须是整数。

  求知足这个条件的不一样直角三角形的个数。

【数据格式】
输入一个整数 n (0<n<10000000) 表示直角三角形斜边的长度。
要求输出一个整数,表示知足条件的直角三角形个数。

例如,输入:

5

程序应该输出:

1

再例如,输入:

100

程序应该输出:

2

再例如,输入:

3

程序应该输出:

0


资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms


请严格按要求输出,不要多此一举地打印相似:“请您输入...” 的多余内容。

全部代码放在同一个源文件中,调试经过后,拷贝提交该源码。

注意: main函数须要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操做系统的特殊函数。
注意: 全部依赖的函数必须明确地在源文件中 #include <xxx>, 不能经过工程设置而省略经常使用头文件。

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

#include <iostream>
#include <iomanip>
#include <cmath>
 
using namespace std;
int main()
{
    long long m;
    int count = 0;
 
    cin >> m;
 
    int t = m*m;
    for (long long i = 1; i < m; i++)
    {
        long long j = sqrt(t - i*i);
        if( j*j + i*i == t)
            count++;
    }
    cout << count/2;
    
    system("pause");
}

第六题

你必定据说过“数独”游戏。


如【图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


再例如,输入:

800000000
003600000
070090200
050007000
000045700
000100030
001000068
008500010
090000400


程序应该输出:

812753649
943682175
675491283
154237896
369845721
287169534
521974368
438526917
796318452


资源约定:
峰值内存消耗 < 256M
CPU消耗  < 2000ms


请严格按要求输出,不要多此一举地打印相似:“请您输入...” 的多余内容。

全部代码放在同一个源文件中,调试经过后,拷贝提交该源码。

注意: main函数须要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操做系统的特殊函数。
注意: 全部依赖的函数必须明确地在源文件中 #include <xxx>, 不能经过工程设置而省略经常使用头文件。

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

#include <iostream>
using namespace std;
 
char map[10][10];
bool check(int  x,int y,char ch)
{
    for (int j = 0; j < 9; j++)
    {
        if(map[x][j] == ch || map[j][y] == ch)
        {
            return false;
        }
    }
    int tx = x/3*3;
    int ty = y/3*3;
 
    for (int i = tx; i < tx+3; i++)
    {
        for (int j = ty; j < ty+3; j++)
        {
            if(map[i][j] == ch)
                return false;
        }                
    }
    return true;
}
void dfs(int x,int y)
{
    if(y > 8)
    {
        for (int i = 0; i < 9; i++)
            cout << map[i] << endl;       
        return;
    }
    if(map[x][y] == '0')
    {
        for (char i = '1'; i <= '9'; i++)
        { 
            if(check(x,y,i) == true)
            {
                map[x][y] = i;
                dfs( (x + 1) % 9, y + (x + 1) / 9);
                map[x][y] = '0';
            }
        }
    }
    else
    {
       dfs( (x + 1) % 9, y + (x + 1) / 9);
    }
}
int main()
{
    for (int i = 0; i < 9; i++)
        cin >> map[i];
 
    dfs(0,0);
    
    system("pause");
}

第七题


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 <xxx>, 不能经过工程设置而省略经常使用头文件。

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

 方法(1):

#include <iostream>
#include <cstring> 
using namespace std;
int m,grade[100005],flag[100005],a[100005];
int count = 0;
 
void dfs(int step,int end)
{
    if (step == end+1)
    {
        /* 打印加入敢死队士兵的名单
        for (int i = 1; i < step; i++)
            cout << a[i];
        cout << endl;
        */
        count++;
        return;    
    }
    for (int i = 1; i <= m; i++)
    {
        if(flag[i] == 0)    //若是i号士兵没有被选择
        {
            if(flag[ grade[i] ] == false && i > a[step-1]) //检查:i号士兵的上级 是否加入敢死队;
                                            //i > a[step-1]: 是为了保证不会出现重复序列,好比有了123,就不能有312;
            {
                flag[i] = 1;
                a[step] = i;
                dfs(step + 1, end);
                flag[i] = 0 ;
            }
        }
    }
    
}
int main()
{
    cin >> m;
    grade[1] = 0; //将军的上级 为0号
    for (int i = 2; i <= m; i++)
    {
        cin >> grade[i];  // i号士兵 的 上级 为,grade[i]
    }
    for (int i = 1; i <= m; i++)    // 选择1个士兵加入敢死队 到 选择m个士兵加入敢死队
    {
        memset(flag,0,sizeof(flag));    //每次清空标志位
        dfs(1,i);           
    }
    cout << count % 10007 << endl;
    system("pause");
}

方法(2):

参考文章:http://www.javashuo.com/article/p-gyujlssf-ek.html

                  https://www.cnblogs.com/pengchuan/p/8635514.html

#include <stdio.h>
int n,a[100001],x[100001];
int sum=0;
bool place(int c,int b)
{
    if(b==1&&x[a[c]]==1) 
        return false;
    return true;
}
void dfs(int t){
    if(t>n)
    {
        sum++;
    }
    else
    {
        for(int i=1;i>=0;i--)    //来 或者 不来 两种状况
        {            
            if(place(t,i))
            {
                x[t]=i;
                dfs(t+1);
            }
            else 
                continue;
        }
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=2;i<=n;i++)
        scanf("%d",&a[i]);
    dfs(1);
    sum--;
    printf("%d",sum%10007); 
    return 0;
}