HRBU_20211108训练
B - Wave
题意
一个序列称为“波”,至少有两个元素,在奇数位数字应该相同,偶数位的数字相同,求这样的子序列至少多长?
例如1212,是符合题意的要求,而它的长度为4,这样的一直重复下去的就是正确的,算出长度即可。
思路
这是一道DP题,首先先明确一点的是如果没有符合的子序列那么最短的长度为2,其次我觉得最重要的一点是找出状态转换方程dp[j][num] = dp [num][j] + 1 .
代码
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int dp[110][110];
int a[110];//标记是否之前出现
int main()
{
int n,c;
while(scanf( "%d %d",&n,&c)==2)
{
int num,len=0;
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
for(int i=1; i<=n; i++)
{
scanf("%d",&num);
a[num]=1;//标记为1
for(int j=1; j<=c; j++)
{
if(j==num || a[j]==0)continue;
if(dp[num][j]==0)
dp[j][num]=2;
else
dp[j][num]=dp[num][j]+1;
len=max(len,dp[j][num]);
}
}
printf("%d\n",len);
}
}
C - String
题意
选择一个字符串,长度为n,只有四个字母’’ a “, " v”, ’ i ‘,’ n ';
计算字母是“ avin ”的概率。
思路
长度为n即它的概率为1/n,计算出所有字母的个数除以四个1/n的概率。
代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[5]={
0};
int main()
{
int n;
cin>>n;
string s;
cin>>s;
int ans,sum;
for(int i=0;i<n;i++)
{
if(s[i]=='a')a[0]++;
if(s[i]=='v')a[1]++;
if(s[i]=='i')a[2]++;
if(s[i]=='n')a[3]++;
}
ans = a[0]*a[1]*a[2]*a[3];
sum =n*n*n*n;
if(ans==0)cout<<"0/1"<<endl;
else
{
int gcd = __gcd(ans,sum);
ans=ans/gcd;
sum = sum/gcd;
cout<<ans<<"/"<<sum<<endl;
}
}
D - Traffic
题意
本题的题意是东西方向的车在ai的时间通过,南北方向的车在bi的时间通过,但是两个方向的车不能在同一个时间通过,所以计算南北方向的车需要等待多久时间。
思路
暴力枚举
代码
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int a[1010],b[1010],c[1010];
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int j=1;j<=m;j++)
scanf("%d",&b[j]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i]>=b[j])
c[a[i]-b[j]]=1;
}
}
for(int i=0;i<=1000;i++)
{
if(!c[i])
{
printf("%d\n",i);
break;
}
}
}
}
F - Budget
题意
输入一个整数n,输入n组数据,分别是有三位小数的数,四舍五入之后,保留两位小数,计算保留两位小数后的误差是多少
思路
用char保存,从后面倒着开始就算,求出最后一位数,一开始是判断小数是否大于五位,如果大于五位,求出最后一位数,用10-最后一位数,如果是小于五位,就是直接是该数。
代码
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
char a[1005];
int main()
{
int n;
scanf("%d",&n);
double x=0;
for(int i=0;i<n;i++)
{
scanf("%s",a);
int l = strlen(a);
if(a[l-1]>='5')//0.001
{
x+=10.0-(a[l-1]-'0');
//printf("%.5f",x);
}
else
x-=(a[l-1]-'0');
}
printf("%.3f\n",x/1000);
return 0;
}
G - Worker
题意
这题是有n个仓库,m个工人,第i个仓库需要ai个订单,问如何分配工人可以使每个仓库产生的订单数一样,若你能,输出yes,并且输出分配的工人数,若不能,输出NO.
思路
求出所有订单的最小公倍数,用(m/最小公倍数),若能得到整数,则用ai * (m/最小公倍数),即可得到结果
代码
#include<stdio.h>
#include<iostream>
#define ll long long
using namespace std;
int a[1005];
long long gcd(ll x,ll y)//最大公约数
{
return (y==0)?x:gcd(y,x%y);
}
long long gbs(ll x,ll y)
{
return (x*y)/gcd(x,y);
}
int main()
{
int n;
ll m;
while(scanf("%d %lld",&n,&m)!=EOF)
{
ll b=1,sum=0;//最小公倍数
for(int i=1;i<=n;i++)
{
cin>>a[i];
b=gbs(b,a[i]);
}
for(int i=1;i<=n;i++)
{
a[i]=b/a[i];
sum+=a[i];
}
if(m%sum==0)
{
printf("Yes\n");
for(int i=1;i<=n;i++)
{
printf("%lld",a[i]*(m/sum));
if(i<=n-1)printf(" ");
else
printf("\n");
}
}
else
printf("No\n");
}
}
H - Class
题意
已知 a+b,a-b的结果求出a * b
扫描二维码关注公众号,回复:
13303471 查看本文章

思路
相减除以2求出a,相加除以2求出b.超简单!
代码
#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
int a,b;
cin>>a;
cin>>b;
int x=(a+b)/2;
int y=(a-b)/2;
cout<<(x*y)<<endl;
}