题目总链接:
https://nuoyanli.com/contest/32/problems
A:YZJ的牛肉干
题目链接:
https://nuoyanli.com/contest/32/problem/A
题面:
题意:
多组输入,先输入一个n,代表字符串的长度,这个字符串只能有Y,Z,J三个字母组成,其中Z,Z不能连续出现在一起。输出有多少中涂法。
思路:
我们先观察 第一项为3,第二项为8,第三项的方案数位22,此时第三项的值为前两项的值的和乘以2。此时我们猜测规律是 除前两项之外,某项之和等于前两项之和的二倍其实原理我也不清楚 就找规律吧。
参考代码:
#include<stdio.h>
int main()
{
long long int a[45];
a[1] = 3;
a[2] = 8;
for(int i = 3;i <40;i++)
{
a[i] = 2*(a[i-1] + a[i-2]);
}
int n;
while (scanf("%d",&n)!=EOF)
{
printf("%lld\n",a[n]);
}
return 0;
}
B:扫雷
题目链接:
https://nuoyanli.com/contest/28/problem/B
题面:
题意:
输入两个整数n,m,代表n行n列,其中字符*代表雷,我们需要在没雷的地方显示这个没雷的地方的8个方向上存不存在雷,在没雷的位置显示出8个方向中的雷的个数。
思路:
这道题目我是用的相当暴力的方法,其实有简单的办法但是比赛的时候没有想到(还是太垃圾了) 我们就是特判第一行,最后一行,第一列,最后一列,然后其他的都是判断8个方向,这几个需要判断的方向不同所以特判。我的思路就是一句话麻烦。
参考代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
int n,m,i,j;
char ch;
scanf("%d %d",&n,&m);
scanf("%c",&ch);
char a[1000][1000];
for(i=0;i<=n+10;i++)
{
for(j=0;j<=m+10;j++)
{
a[i][j]='0';
}
}
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
scanf("%c",&a[i][j]);
if(a[i][j]!='*')//把不为雷的位置全部请为0字符,方便之后的显示出雷的个数。
a[i][j]='0';
}
scanf("%c",&ch);
}
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
if(i!=0&&j!=0)//特判的情况
{
if(a[i][j]=='*')//暴力判断。。。。。
{
if(a[i-1][j-1]!='*')
{
a[i-1][j-1]=a[i-1][j-1]+1;
}
if(a[i-1][j]!='*')
{
a[i-1][j]=a[i-1][j]+1;
}
if(a[i-1][j+1]!='*')
{
a[i-1][j+1]=a[i-1][j+1]+1;
}
if(a[i][j-1]!='*')
{
a[i][j-1]=a[i][j-1]+1;
}
if(a[i][j+1]!='*')
{
a[i][j+1]=a[i][j+1]+1;
}
if(a[i+1][j-1]!='*')
{
a[i+1][j-1]=a[i+1][j-1]+1;
}
if(a[i+1][j]!='*')
{
a[i+1][j]=a[i+1][j]+1;
}
if(a[i+1][j+1]!='*')
{
a[i+1][j+1]=a[i+1][j+1]+1;
}
}
}
if(i==0&&j==0)
{
if(a[i][j]=='*')
{
if(a[i+1][j]!='*')
{
a[i+1][j]=a[i+1][j]+1;
}
if(a[i+1][j+1]!='*')
{
a[i+1][j+1]=a[i+1][j+1]+1;
}
if(a[i][j+1]!='*')
{
a[i][j+1]=a[i][j+1]+1;
}
}
}
if(i==0&&j!=0)
{
if(a[i][j]=='*')
{
if(a[i][j-1]!='*')
{
a[i][j-1]=a[i][j-1]+1;
}
if(a[i][j+1]!='*')
{
a[i][j+1]=a[i][j+1]+1;
}
if(a[i+1][j-1]!='*')
{
a[i+1][j-1]=a[i+1][j-1]+1;
}
if(a[i+1][j]!='*')
{
a[i+1][j]=a[i+1][j]+1;
}
if(a[i+1][j+1]!='*')
{
a[i+1][j+1]=a[i+1][j+1]+1;
}
}
}
if(j==0&&i!=0)
{
if(a[i][j]=='*')
{
if(a[i-1][j]!='*')
{
a[i-1][j]=a[i-1][j]+1;
}
if(a[i-1][j+1]!='*')
{
a[i-1][j+1]=a[i-1][j+1]+1;
}
if(a[i][j+1]!='*')
{
a[i][j+1]=a[i][j+1]+1;
}
if(a[i+1][j]!='*')
{
a[i+1][j]=a[i+1][j]+1;
}
if(a[i+1][j+1]!='*')
{
a[i+1][j+1]=a[i+1][j+1]+1;
}
}
}
}
}
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
printf("%c",a[i][j]);
}
if(i!=n-1) printf("\n");
}
}
C.签到题它又来了
题目链接:
https://nuoyanli.com/contest/28/problem/C
题面:
思路:
这道题目其实也就是一个简单的结构体排序,这种题目我之前的题解有详细的分析,这里就不详细分析了,我这次只要说一下我去重的方法,根据排序结束后,我们第一个数是一定会输出的,这时候我们就只需要不断判断后面一位是否与前一位相等,如果相等就不输出,如果不相同,就正常输出,这时候就完成了去重的工作。其他的思路基本就是之前题目结构体排序的思维。
参考代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct cfx
{
int bh;
int c;
int k;
}a[100000];
bool cmp(cfx a,cfx b)//定义排序方式的函数
{
if(a.bh==b.bh)
{
if(a.c==b.c)
{
return a.k<b.k;
}
else
return a.c<b.c;
}
else
return a.bh<b.bh;
}
int main()
{
int n,m,i,t;
scanf("%d",&n);
while(n--)
{
int m;
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a[i].bh,&a[i].c,&a[i].k);
if(a[i].c<a[i].k)//这个if的作用是将c中存储的一定是长的那一边,即就是长,而k中的存储的为宽。
{
t=a[i].c;
a[i].c=a[i].k;
a[i].k=t;
}
}
sort(a,a+m,cmp);
printf("%d %d %d\n",a[0].bh,a[0].c,a[0].k);
for(i=1;i<m;i++)
{
if(a[i].bh==a[i-1].bh&&a[i].c==a[i-1].c&&a[i].k==a[i-1].k)//这是判断去重重复的操作
{
}
else
printf("%d %d %d\n",a[i].bh,a[i].c,a[i].k);
}
}
return 0;
}
D:万德隆购物
题目链接:
https://nuoyanli.com/contest/28/problem/D
题面:
思路:
参考代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
int n,m,sum;
scanf("%d%d",&n,&m);
sum=(2*n*m)/(m+n);
printf("%d",sum);
}
E:三生三世
题目链接:
https://nuoyanli.com/contest/28/problem/E
题面:
思路:
这道题目我们首先要特判两个字符串完全相等的情况。然后再将两个字符串继续sort排序,然后在接着判断两个字符串是否完全相等,如果完全相等则就是子串,输出yes,若不是输出no。
参考代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
int n,i,j,ans=0;
scanf("%d",&n);
char a[n+10];
char b[n+10];
scanf("%s",a);
scanf("%s",b);
if(strcmp(a,b)==0)//判断两个字符是否完全相等
{
printf("no");
}
else//如果不相等就对其继续ssort排序,如果排序之后完全相等就证明是子串。
{
sort(a,a+n);
sort(b,b+n);//对两个字符串继续sort排序
if(strcmp(a,b)==0)//判断排序之后的字符串是否完全相等
{
printf("yes");
}
else
{
printf("no");
}
}
return 0;
}
F:卖火柴的lly
题目链接:
https://nuoyanli.com/contest/28/problem/F
题面:
题意:
从0到9对应不同的火柴数目,输入一个数,代表我们有的火柴数,接下来我们要使得已有的火柴数正好满足一个等式满足a+b=c,我们需要输出这个数目下的火柴可以组成多少个这样的等式,其他+,=分别使用两个火柴数目。
思路:
这道题目我们最难实现的就是数字的相加的等式要转换为火柴数目的相加,而实现这个我们可以通过定义一个函数,我们先得出满足a+b=c,然后定义一个函数使得数字改为对应的火柴数目,然后再判断火柴数目是否满足刚好等于给定的火柴数目,如果满足就加1.这道题目思路就这样,然后就是代码实现了。
参考代码:
#include <cstdio>
int fun(int x)
{
int ans=0,f[10]= {6,2,5,5,4,5,6,3,7,6};//将下标作为数字,该下标对应的数组存储的值作为需要的火柴数。
while(x/10!=0)
{
ans+=f[x%10];
x=x/10;
}
ans+=f[x];//将数字对应的需要的火柴数目求出来
return ans;
}
int main()
{
int a,b,c,m,ans=0;
scanf("%d",&m);
for (a = 0; a<= 1111; a++)
{
for(b=0; b<= 1111; b++)
{
c=a+b;
if((fun(a)+fun(b)+fun(c))==m-4)//判断是否存在等式使得a+b=c的等式需要的火柴数满足,若满足则加1
{
ans++;
}
}
}
printf("%d",ans);//输出这个数目的火柴数目下能够构成的等式数目
return 0;
}
G:进位
题目链接:
https://nuoyanli.com/contest/28/problem/G
题面:
思路:
这道题目就是求两个数字相加的进位次数,我们可以通过一位一位不断的判断,我们先判断个位数相加,如果超过10就要进位,然后在把相加/10的数值加到10位,就只要操作3次,就可以判断出进位的次数了。
参考代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
int m,n;
while(scanf("%d%d",&m,&n)!=EOF)
{
int a,b,c,d,e,f,k=0,x=0,y=0;
if(m==0&&n==0)
{
break;
}
a=m%10;//第一个数字的个位数
b=n%10;//第二个数字的个位数
if(a+b>=10)//判断是否大于10需要进位
{
k=k+1;//进位次数加1
x=(a+b)/10;//加到10位数的数值
}
c=n/10%10;
d=m/10%10;
if((c+d+x)>=10)//判断前面进位需要加的数值和两个数的十位数相加是否大于10,下面的操作基本重复
{
k=k+1;
y=(c+d+x)/10;
}
e=n/100;
f=m/100;
if((e+f+y)>=10)
{
k=k+1;
}
printf("%d\n",k);
}
}
H:最直接的题
题目链接:
https://nuoyanli.com/contest/28/problem/H
题面:
题意:
输入n个数字,一个数字加2或者减2的代表为0,加1或者减1的代价为1,我们需要输出花费代价最少的代价为多少。
思路:
这道题目其实理清思路就特别简单,我们可以把所有的数字通过不断减2使得这些数字变成只有1或者2,这时候要使得代价最小,是不是加1减1的次数要少,而我们就只需要判断奇数和偶数的个数大小,把个数小的转换为个数大的就是花费代价最小的方案了,所有这道题目其实就是判断奇数个数和偶数个数的大小比较。
参考代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
int n,k=0,i,m=0;
scanf("%d",&n);
int a[n+10];
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i]%2==0)
{
m=m+1;//计算偶数个数
}
else
{
k=k+1;//计算奇数个数
}
}
if(m>k)//判断大小
{
printf("%d",k);
}
else
{
printf("%d",m);
}
return 0;
}
I:淘宝盖楼
题目链接:
https://nuoyanli.com/contest/28/problem/I
题面:
题意:
题意就是找人帮忙盖楼,就是她一个个选择,到每次选择都不会选择比自己选的等级低的人。然后输出最后的等级。
思路:
这道题目就是简单的累加加了一个判断,我们需要确保你选那个一定比你前面出现过的任何数字都大,我们需要实现这个操作其实就只需要定义一个maxe,使得它一开始特别小,然后继续判断和赋值,就可以判断这个数字是不是比你前面出现的数字都要大。
参考代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
long long n,sum,i,maxe;
scanf("%lld",&n);
long long a[n+10];
for(i=0;i<n;i++)
{
scanf("%lld",&a[i]);
}
sum=a[0];
maxe=a[0];
for(i=1;i<n;i++)
{
if(a[i]<maxe);
if(a[i]>=maxe)//判断a[i]是不是比前面的数字都大
{
maxe=a[i];//如果大于,把a[i]的数值赋值给maxe
sum=sum+a[i];//同时这个人帮忙盖楼
}
}
printf("%lld",sum);//输出最后帮忙盖楼的等级总数
return 0;
}
J:Belief
题目链接:
https://nuoyanli.com/contest/32/problem/J
题面:
思路:
白给的题,虽然是英文题,但是相当简单啊
参考代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
long long n,sum;
scanf("%lld",&n);
while(n--)
{
printf("I love ACM,ACM is my belief!");
if(n!=0) printf("\n");
}
return 0;
}
K:爱我中华
题目链接:
https://nuoyanli.com/contest/32/problem/K
题面:
思路:
白送的题目,就是1949+n,话不多说,代码附上。
参考代码
#include<stdio.h>
int main()
{
long long n,sum;
scanf("%lld",&n);
sum=1949+n;
printf("%lld",sum);
return 0;
}
M:货车
题目链接:
https://nuoyanli.com/contest/32/problem/M
题面:
题意:
输入一个n,m分别代表仓库中本来有的货物个数并且仓库中本来的货物的编号是从1到n。接下来继续m次操作,如果输入1代表放入,就接着输入一个编号。代表放入货物的编号,如果输入的2的话,就代表要拿出最外面的那个货物。然后输出最后剩余的货物的编号,总最外面的编号开始输出。
思路:
这道题目就是栈的题目,这里我是使用数组进行模拟其过程,我们首先把前面有的货物对应的编号存储到数组中去,然后继续判断,如果输入的为1,就继续输入一个数字,我们这时候就将这个数字(就是货物对应的编号)存储到数组中去,如果之前输入的为2,我们就直接减去数组的一位,实现删除的操作。然后就这样子判断m次,最后把数组逆序输出就行了。
参考代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
int n,m,i,b;
int a[10000];
scanf("%d%d",&n,&m);
for(i=0; i<n; i++)
{
a[i]=i+1;//把仓库中本来的有的货物先存储到数组中去
}
while(m--)//进行m次操作
{
scanf("%d",&b);
if(b==1)//判断是否是放入货物还是拿出货物
{
scanf("%d",&a[n++]);//如果放入先存储到数组中去,然后n++
}
if(b==2)
{
n=n-1;//如果有删除就n--
}
}
if(n==0)//特判仓库中没有货物的情况了,就输出no
{
printf("NO");
}
else
{
for(i=n-1; i>=0; i--)//逆序输出
{
printf("%d ",a[i]);
}
}
}