2021-02-22

今天的比赛占了五个小时(真长),自己看一两个小时左右的书以及梳理了自己今天解题的思路。

D - Chess
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1
#.
.#
4 4
…#
…#.
.#…
#…
-1 -1
Sample Output
2
1

其实这道题是我们之前刷过的题组里的原题,奈何我当时懒没去做这道题,于是今天花了点时间想怎样在N皇后那道题的基础上做这道题,哼唧哼唧,以后不能偷懒了

这是代码:

#include<stdio.h>
#include<string.h>
int count=0,book[10],str[10][10];
void fun(int step,int n,int k,int t)
{
   // printf("t=%d\n",t);
    int i=0;
    if(t==k)
    {
        count++;
        return ;
    }
    for(i=0;i<n;i++)
    {
        if(book[i]==0&&str[step][i]=='#')
        {
            //printf("OK ");
            book[i]=1,t++;
            fun(step+1,n,k,t);
            book[i]=0,t--;
        }
    }
    if(step<n) fun(step+1,n,k,t);
    return ;
}
int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k))
    {
        if(n==-1&&k==-1) break;
        count=0;
        int i=0,j=0;
        for(i=0;i<n;i++)
        {
            getchar();
            for(j=0;j<n;j++)
                scanf("%c",&str[i][j]);
        }
        //printf("%s\n",str);
        fun(0,n,k,0);
        printf("%d\n",count);
        count=0;
        memset(book,0,10);
        memset(str,'\0',100);
    }
    return 0;
}

J - Holiday
School holidays come in Berland. The holidays are going to continue for n days. The students of school №N are having the time of their lives and the IT teacher Marina Sergeyevna, who has spent all the summer busy checking the BSE (Berland State Examination) results, has finally taken a vacation break! Some people are in charge of the daily watering of flowers in shifts according to the schedule. However when Marina Sergeyevna was making the schedule, she was so tired from work and so lost in dreams of the oncoming vacation that she perhaps made several mistakes. In fact, it is possible that according to the schedule, on some days during the holidays the flowers will not be watered or will be watered multiple times. Help Marina Sergeyevna to find a mistake.
Input
The first input line contains two numbers n and m (1 ≤ n, m ≤ 100) — the number of days in Berland holidays and the number of people in charge of the watering respectively. The next m lines contain the description of the duty schedule. Each line contains two integers ai and bi (1 ≤ ai ≤ bi ≤ n), meaning that the i-th person in charge should water the flowers from the ai-th to the bi-th day inclusively, once a day. The duty shifts are described sequentially, i.e. bi ≤ ai + 1 for all i from 1 to n - 1 inclusively.
Output
Print “OK” (without quotes), if the schedule does not contain mistakes. Otherwise you have to find the minimal number of a day when the flowers will not be watered or will be watered multiple times, and output two integers — the day number and the number of times the flowers will be watered that day.
Examples
Input
10 5
1 2
3 3
4 6
7 7
8 10
Output
OK
Input
10 5
1 2
2 3
4 5
7 8
9 10
Output
2 2
Input
10 5
1 2
3 3
5 7
7 7
7 10
Output
4 0

水题一个没啥好讲的
代码如下:

#include<stdio.h>

int main()
{
    int n,m,arry[110]= {0};
    scanf("%d%d",&n,&m);
    int i=0,j=0,a,b;
    for(i=0; i<m; i++)
    {
        scanf("%d%d",&a,&b);
        for(j=a; j<=b; j++)
            arry[j]++;
    }
    int bool=0;
    for(i=1; i<=n; i++)
        if(arry[i]!=1)
        {
            bool=1;
            break;
        }
    if(bool==0) printf("OK\n");
    else printf("%d %d\n",i,arry[i]);
    return 0;
}

E - Good Ticket
最近小A得到了一串号码——一个包含了 n 个数字 a_1 a_2 … a_n的数列。小A认为一个数列是超级号码,如果它能被分为两个或更多的有相同值的部分。例如,号码350178 是超级号码因为它可以被分为三个部分350, 17 和 8: 3+5+0=1+7=8。每一个数字只能属于一个部分 。
帮小A看看他的号码是不是超级号码。
Input
第一行包含一个整数 n (2 <= n <= 100) — 号码的数字个数
第二行包含 n 个数字 a_1 a_2 … a_n (0 <= a_i <= 9) — 小A的号码. 数字间没有空格。
Output
如果是超级号码则输出 “YES”, 否则输出 “NO” (不带引号)。
Examples
Input
5
73452
Output
YES
Input
4
1248
Output
NO
Note
第一个样例分为了三部分 7, 34 和 52: 7=3+4=5+2。
第二个样例不是超级号码。

这道题让我对深搜的用法有了新的了解(虽然我现在也搞不懂深搜到底是啥子)所以特意花了点时间梳理思路并且做注释,万一以后忘了还可以来回忆一下哈哈
代码及注释如下:

#include<stdio.h>
#include<string.h>
int bool=0;

int change(char x)
{
    return x-'0';
}//这个函数用来将字符转换成相应整型
void fun(char str[],int flag,int n)
{
    int t=0,i=0;
    if(flag==0)//若flag为0那么只有两种可能:1、现在正在选择第一部分的数字序列范围,2、该字符串由0组成
        for(i=0; i<n; i++)
        {
            if(bool==1) return ;//如果bool为1,则代表已经找到了能证明原号码为超级号码的数字序列组合方案,故结束该函数无需再进行查找
            t+=change(str[i]);//用t来记录第一部分的数字序列之和,将其作为为标准
            //printf("t=%d\n",t);
            fun(str+i+1,t,n-i-1);//将指针移向下一位并将运算跳转到第21行所示
            if(i==n-1&&t==0) bool=1;//这一步很重要,因为如果没有这一步的话那么由0组成的字符串将不会被判断为“超级号码”
        }
    else//若flag不为0,则代表前面的步骤中已经确定了每一部分数字序列之和,只需对后面的字符串进行判断
        for(i=0; i<n; i++)
        {
            if(bool==1) return ;//已找到能证明原号码为超级号码的数字序列组合方案,结束此函数
            t+=change(str[i]);//记录当下部分录入的数字序列之和
            if(i==n-1)//若已查找到原号码最后一位则进行进一步判定
            {
                if(t==flag) bool=1;//若最后一部分的数字序列之和与之前若干数字序列之和皆相等,那么bool转换成1
                return ;
            }
            //当下查找的数字不是原字符串最后一位
            if(t==flag)//如果该部分的数字序列之和满足与前面确定的“标准和”相等
                fun(str+i+1,flag,n-i-1);//则进行下一部分数字序列筛选
            if(t>flag)//如果t大于事先选定的标准和,则证明标准和选取不当
                return;//于是跳回之前的步骤重新选取标准和
        }
}

int main()
{
        bool=0;
        int i=0,n;
        char str[110];
        scanf("%d",&n);
        getchar();
        gets(str);
        fun(str,0,n);
        if(bool==1) printf("YES\n");
        else printf("NO\n");
    return 0;
}

好了好了不早了睡觉,熬夜伤肝命最重要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值