目录
B - Wave
题意:
给一个n个整数的序列,整数范围为1~c,求一个子序列满足偶数位上数字相同,奇数位上数字相同,且奇偶位上的数字不同。
输出满足要求的最长子序列的长度。
思路:
简单 DP,设是以 结尾, 为结尾前一个数字的最长合法 wave,
则有状态转移方程:
。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int dp[110][110];
int a[maxn];
int main()
{
int n,c,x;
while(cin>>n>>c)
{
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++)
{
cin>>a[i];
}
int ans=0;
for(int i=1; i<=c; i++)
{
if(a[1]==i)
{
dp[a[1]][i]=0;
}
else
{
dp[a[1]][i]=1;
}
}
for(int i=2; i<=n; i++)
{
for(int j=1; j<=c; j++)
{
if(a[i]==j)
dp[a[i]][j]=0;
else
dp[a[i]][j]=dp[j][a[i]]+1;
ans=max(ans,dp[a[i]][j]);
}
}
cout<<ans<<endl;
}
}
C - String
题意:一个长度为n的字符串,每次从字符串中随机取出一个字符(可放回)。取4次,问按照取字符的顺序组成的字符串有多少几率是"avin"?
请输出最简化分数形式。若概率为0,则输出"0/1"。
思路:统计每种字符出现的次数,根据乘法原理计算概率。输出最简化分数形式,求一下分子分母除以其最大公因子。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e3+10;
ll a[maxn];
ll b[maxn];
map<char,int> mp;
int main()
{
int n;
while(cin>>n)
{
mp.clear();
string s;
cin>>s;
for(int i=0;i<n;i++)
mp[s[i]]++;
ll y=n*n*n*n;
ll x=mp['a']*mp['v']*mp['i']*mp['n'];
if(x==0) cout<<"0/1"<<endl;
else
{
ll z=__gcd(x,y);
x/=z;
y/=z;
cout<<x<<"/"<<y<<endl;
}
}
}
D - Traffic
题意:
有一个十字路口,分为东西方向和南北方向。两个方向在不同的时间点会有车辆经过,如果同一个时间点两个方向都有来车,就会发生交通事故,为了避免事故发生。于是规定,东西方向的车优先行驶,将南北方向的车辆的的通过时间向后推迟(整体推迟),求一个最小推迟时间使得东西方向与南北方向的车辆的通过时间点不会重叠。
思路:
东西方向车辆等待时间a[j],南北方向b[i],我们要找到最小推迟时间ans,使得。标记a数组,遍历b数组,如果当前的b[i]+ans会与a中元素相撞,则ans++。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
int a[maxn],b[maxn],vis[maxn];
int main()
{
int n,m;
while(cin>>n>>m)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
cin>>a[i];
vis[a[i]]=1;
}
for(int i=0;i<m;i++)
{
cin>>b[i];
}
int ans=0;
for(int i=0;i<m;i++)
{
if(vis[b[i]+ans]==1)
{
i=0;
ans++;
}
}
cout<<ans<<endl;
}
}
F - Budget
题意:将三位小数四舍五入为两位小数,并判断误差是多少。
思路:字符串输入该数,然后用对最后一位小数进行判断:
设b为最后一位小数(即小数点后第3位)
(1)如果b<=4,那么答案加上-b*0.001。
(2)如果b>=5,那么答案加上(10-b)*0.001。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
int a[maxn],b[maxn],vis[maxn];
int main()
{
int n;
while(cin>>n)
{
string a;
double sum=0;
for(int i=0;i<n;i++)
{
cin>>a;
int x=a.length();
if(a[x-1]-'0'>=5)
{
sum+=((10-(a[x-1]-'0'))*0.001);
}
else sum-=((a[x-1]-'0')*0.001);
}
printf("%.3lf\n",sum);
}
}
G - Worker
题意:有 n 个车间, m 个工人。在第 i 个车间工作的工人可以完成 个任务。请你求出一个分配工人的方案,使得每个车间最后完成的任务总数是相同的。没有方案则输出" NO",可以分配输出“YES”及其每个车间的工人人数。
思路:
各仓库分配人数的比例应为
很可惜它们不是整数,我们令(M为数组的最小公倍数)
各仓库分配人数的比例应为
则第i个仓库需要人,如果该值不是整数,则输出NO。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
ll a[maxn],b[maxn];
ll gcd(int aa,int bb)
{
return bb==0?aa:gcd(bb,aa%bb);
}
ll lcm(int aa,int bb)
{
return aa/gcd(aa,bb)*bb;
}
int main()
{
ll n,m;
while(cin>>n>>m)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
ll sum=1;
ll sum1=0;
for(ll i=0;i<n;i++)
{
cin>>a[i];
sum = lcm(sum,a[i]);
}
for(ll i=0;i<n;i++)
{
b[i]=sum/a[i];
sum1+=b[i];
}
if(m%sum1==0)
{
cout<<"Yes"<<endl;
for(ll i=0;i<n;i++)
{
if(i==0)
{
cout<<(m/sum1)*b[i];
}
else
{
cout<<" "<<(m/sum1)*b[i];
}
}
cout<<endl;
}
else
{
cout<<"No"<<endl;
}
}
}
H - Class
题意:
思路:
则
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int x,y;
cin>>x>>y;
cout<<(x*x-y*y)/4<<endl;
}