FJUT2017寒假训练二题解

Posted seventh成长中---

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FJUT2017寒假训练二题解相关的知识,希望对你有一定的参考价值。

 

A题

题意:让你找出唯一的一个四位数,满足对话时的要求。

思路:因为是4位数,可以直接从1000-9999遍历一遍,判断是否有唯一的数能满足所有条件,如果不是唯一的或者没有满足条件的数就输出Not sure。特别丑的代码附上。。。

 

  1 #include<stdio.h>
  2 int a[10000],b[10000],c[10000];
  3 int main()
  4 {
  5     int n;
  6     while(~scanf("%d",&n))
  7     {
  8         if(n==0)break;
  9         int i,flag=0,ans,j,k;
 10         for(i=1;i<=n;i++)
 11             scanf("%d%d%d",a+i,b+i,c+i);
 12         for(i=1000;i<=9999;i++)
 13         {
 14             int a1,a2,a3,a4,i1,i2,i3,i4,bx=0,cx=0,flg=1;///ax代表a[i]的第x个数,ix代表i的第x个数
 15             for(j=1;j<=n;j++)
 16             {
 17                 bx=0;cx=0;
 18                 a1=a[j]/1000;
 19                 a2=(a[j]/100)%10;
 20                 a3=(a[j]/10)%10;
 21                 a4=a[j]%10;
 22                 i1=i/1000;
 23                 i2=(i/100)%10;
 24                 i3=(i/10)%10;
 25                 i4=i%10;
 26                 if(a1==i1)///先判断位置正确的
 27                     cx++;
 28                 if(a2==i2)
 29                     cx++;
 30                 if(a3==i3)
 31                     cx++;
 32                 if(a4==i4)
 33                     cx++;
 34                 if(a1==i1)///这里如果判和i中的一个数相等,就让i中的那个数为11,就不会再和下个数匹配了,防止出现当类似ai=1111,i=1234的时候a1,a2,a3,a4都和i1匹配成功的情况。
 35                     {
 36                         bx++;
 37                         i1=11;
 38                     }
 39                 else if(a1==i2)
 40                     {
 41                         bx++;
 42                         i2=11;
 43                     }
 44                 else if(a1==i3)
 45                     {
 46                         bx++;
 47                         i3=11;
 48                     }
 49                 else if(a1==i4)
 50                     {
 51                         bx++;
 52                         i4=11;
 53                     }
 54                 if(a2==i1)
 55                     {
 56                         bx++;
 57                         i1=11;
 58                     }
 59                 else if(a2==i2)
 60                     {
 61                         bx++;
 62                         i2=11;
 63                     }
 64                 else if(a2==i3)
 65                     {
 66                         bx++;
 67                         i3=11;
 68                     }
 69                 else if(a2==i4)
 70                     {
 71                         bx++;
 72                         i4=11;
 73                     }
 74                     if(a3==i1)
 75                     {
 76                         bx++;
 77                         i1=11;
 78                     }
 79                 else if(a3==i2)
 80                     {
 81                         bx++;
 82                         i2=11;
 83                     }
 84                 else if(a3==i3)
 85                     {
 86                         bx++;
 87                         i3=11;
 88                     }
 89                 else if(a3==i4)
 90                     {
 91                         bx++;
 92                         i4=11;
 93                     }
 94                     if(a4==i1)
 95                     {
 96                         bx++;
 97                         i1=11;
 98                     }
 99                 else if(a4==i2)
100                     {
101                         bx++;
102                         i2=11;
103                     }
104                 else if(a4==i3)
105                     {
106                         bx++;
107                         i3=11;
108                     }
109                 else if(a4==i4)
110                     {
111                         bx++;
112                         i4=11;
113                     }
114                     if(bx!=b[j]||cx!=c[j])
115                     {
116                         flg=0;
117                         break;
118                     }
119             }
120             if(flg)
121             {
122 
123                 ans=i;
124                 flag++;
125             }
126         }
127         if(flag==1)
128             printf("%d\\n",ans);
129         else
130             printf("Not sure\\n");
131     }
132 }
AC代码

 

B题

题意:打老鼠,在某一个时刻把所有的老鼠打下去。

思路:对于一个[l,r]区间,一定是从最左或者最右开始打,因为如果你从中间开始打,最后还是要经过最左最右,这时候中间位置会经过两次,所以中间开始一定不是最优方案。这样的话问题就变成了一个区间dpdp[l][r][1]代表从右边开始打完[l,r]区间的老鼠,dp[l][r][0]代表从左边开始打完[l,r]区间的老鼠,这样的话有状态转移方程:

dp[l][r][0]=min(dp[l+1][r][0]+d[l+1]-d[l],dp[l-1][r][1]+d[r]-d[l])

dp[l][r][1]=min(dp[l][r-1][0]+d[r]-d[l],dp[l][r-1][1]+d[r]-d[r-1])

然后开个数组记忆走过的路线

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 const int INF=999999999;///INF判断能不能在老鼠爬起来之前打完
 4 int t[1000010],d[1000010];
 5 int dp[202][202][2];///dp[i][j][0]代表打完[i,j]区间的老鼠并且停留在左端点用的时间
 6                     ///dp[i][j][1]代表打完[i,j]区间的老鼠并且停留在右端点用的时间
 7 int route[202][202][2];///记录路线的数组为0代表往右走遇见第一个冒出头的老鼠。
 8 int main()             ///为1代表往左走遇见第一个冒出头的老鼠。
 9 {
10     int n;
11     while(~scanf("%d",&n))
12     {
13         int i,j,l,r,temp;
14         for(i=1;i<=n;i++)
15             scanf("%d",t+i);
16         for(i=1;i<=n;i++)
17             scanf("%d",d+i);
18         memset(dp,0,sizeof(dp));
19         for(l=2;l<=n;l++)
20         {
21             for(i=1;i<=n-l+1;i++)
22             {
23                 j=i+l-1;
24                 if(dp[i+1][j][0]+d[i+1]-d[i]<=dp[i+1][j][1]+d[j]-d[i])
25                     {
26                         dp[i][j][0]=dp[i+1][j][0]+d[i+1]-d[i];
27                         route[i][j][0]=0;
28                     }
29                 else
30                     {
31                         dp[i][j][0]=dp[i+1][j][1]+d[j]-d[i];
32                         route[i][j][0]=1;
33                     }
34                 if(t[i]<=dp[i][j][0])
35                     dp[i][j][0]=INF;
36                 if(dp[i][j-1][0]+d[j]-d[i]<=dp[i][j-1][1]+d[j]-d[j-1])
37                     {
38                         dp[i][j][1]=dp[i][j-1][0]+d[j]-d[i];
39                         route[i][j][1]=0;
40                     }
41                 else
42                     {
43                         dp[i][j][1]=dp[i][j-1][1]+d[j]-d[j-1];
44                         route[i][j][1]=1;
45                     }
46                     if(t[j]<=dp[i][j][1])
47                         dp[i][j][1]=INF;
48             }
49         }
50         if(dp[1][n][0]<INF)///判断起始位置
51         {
52             temp=route[1][n][0];
53             printf("1");
54             l=2,r=n;
55         }
56         else if(dp[1][n][1]<INF)
57         {
58             temp=route[1][n][1];
59             printf("%d",n);
60             l=1,r=n-1;
61         }
62         else
63         {
64             printf("Mission Impossible\\n");
65             continue;
66         }
67         while(l<=r)///路线查找
68         {
69             if(temp==0)
70             {
71                 temp=route[l][r][0];
72                 printf(" %d",l++);
73             }
74             else
75             {
76                 temp=route[l][r][1];
77                 printf(" %d",r--);
78             }
79         }
80         printf("\\n");
81     }
82 }
AC代码

 

C题

题意:一堆单词,找到第一个为B开头的单词,用其他单词和它连接,使得最后一个连接的单词末尾为M

思路:直接暴力深搜就好了

 1 #include<stdio.h>
 2 #include<string.h>
 3 char a[1001][1001];///储存字符串
 4 int dfs(int fi,int count)
 5 {
 6     int i,flag=0;
 7     char temp=a[fi][0];
 8     a[fi][0]=\'0\';///首字母标记为0,就可以避免单词被重复使用
 9     if(a[fi][strlen(a[fi])-1]==\'m\')
10         return 1;
11     for(i=1;i<count;i++)
12         if(a[fi][strlen(a[fi])-1]==a[i][0])
13         {
14             if(dfs(i,count))
15                 return 1;
16         }
17         a[fi][0]=temp;///回溯还原首字母
18         return 0;
19 }
20 int main()
21 {
22     int n=0,i,j,k;
23     while(~scanf("%s",a[++n]))
24     {
25         if(a[n][0]==\'0\')
26         {
27             int flag=0;
28             for(i=1;i<n;i++)
29             {
30                 if(a[i][0]==\'b\')
31                 {
32                     if(dfs(i,n))
33                     {
34                         flag=1;
35                         break;
36                     }
37                 }
38             }
39             if(flag)
40                     printf("Yes.\\n");
41             else printf("No.\\n");
42             n=0;///字符串重新输入
43         }
44     }
45 }
AC代码

D题

题意:第一天给一颗糖,第二、三天给两颗糖,第四、五、六天给三颗糖......以此类推

思路:模拟这个给糖的方法来写

第一颗糖 一

第二颗糖 二

第三颗糖 四

第四颗糖 七

以此类推

从这上面我们可以发现当第n天为1 3 6 10的时候,第二天糖都会多给一个,很容易看出1 3 6 10是一个二阶等差数列,通项公式为an=n*(n+1)/2,由此就可以写出下面的代码。

 

 1 #include<stdio.h>
 2 int main()
 3 {
 4     int n;
 5     while(~scanf("%d",&n))
 6     {
 7         int ans=0,i,r=0;
 8         if(n==0)break;
 9         for(i=1;i<=n;i++)
10         {
11             if(i>r*(r+1)/2)///判断给的糖数是否要增加
12                 r++;
13             ans+=r;
14         }
15          printf("%d %d\\n",n,ans);
16     }
17 }
AC代码

E题

题意:给你一个1-500000内数字,让你把它所有的因数加起来,求出加起来之后的数。

思路:这个题的询问次数很多,一个一个算的话很容易超时,所有我们这里可以进行一个因子和打表的预处理。

 1 #include<stdio.h>
 2 int a[500001];
 3 int main()
 4 {
 5     int i,j;
 6     for(i=1;i<=250000;i++)
 7     {
 8         for(j=i*2;j<=500000;j+=i)
 9             a[j]+=i;
10     }
11     int t;
12     scanf("%d",&t);
13     while(t--)
14     {
15         int c;
16         scanf("%d",&c);
17         printf("%d\\n",a[c]);
18     }
19 }
AC代码

 

 

以上是关于FJUT2017寒假训练二题解的主要内容,如果未能解决你的问题,请参考以下文章

FJUT寒假作业涨姿势题解

几道STL题目(FJUT - OJ STL训练1)

2018年全国多校算法寒假训练营练习比赛(第三场)

FJUT-ACM 寒假作业第1周A题

2018年全国多校算法寒假训练营练习比赛(第五场)题解

2018年全国多校算法寒假训练营练习比赛(第三场)题解