2019CCPC-江西省赛(重现赛)
1001
1002
1003
1004
1005
1006 String (HDOJ 6572)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6572
代码:
#include <bits/stdc++.h> using namespace std; const int maxn=110; int n,cnt[4]; char s[maxn]; int main(){ while(~scanf("%d",&n)){ memset(cnt,0,sizeof(cnt)); scanf("%s",s+1); for(int i=1;i<=n;i++){ if(s[i]=='a') cnt[0]++; if(s[i]=='v') cnt[1]++; if(s[i]=='i') cnt[2]++; if(s[i]=='n') cnt[3]++; } int tmp1,tmp2; if(!cnt[0] || !cnt[1] || !cnt[2] || !cnt[3]){ tmp1=0; } else{ tmp1=cnt[0]*cnt[1]*cnt[2]*cnt[3]; } tmp2=n*n*n*n; int tmp=__gcd(tmp1,tmp2); tmp1/=tmp,tmp2/=tmp; printf("%d/%d\n",tmp1,tmp2); } return 0; }
1007 Traffic (HDOJ 6573)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6573
思路:枚举i和j,b[j]+x=a[i]是不可以的情况,标记此刻的x不可取,最后遍历看x能取的最小值
代码:
#include <bits/stdc++.h> using namespace std; const int maxn=1e5+10; int n,m; int a[maxn],b[maxn],cnt[maxn]; int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<=m;i++){ scanf("%d",&b[i]); } memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i]-b[j]<0) continue; cnt[a[i]-b[j]]++; } } for(int i=0;i<=maxn;i++){ if(cnt[i]==0){ printf("%d\n",i); break; } } } return 0; }
1008 Rng (HDOJ 6574)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6574
思路:打表
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll n;
ll quickpow(ll a,ll b){
if(b<0) return 0;
ll ret=1;
a%=mod;
while(b){
if(b&1) ret=(ret*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ret;
}
ll inv(ll a){
return quickpow(a,mod-2);
}
int main(){
scanf("%lld",&n);
ll ans=((n+1)*inv(2*n))%mod;
printf("%lld\n",ans);
return 0;
}
1009 Budget (HDOJ 6575)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6575
题意:给出1e18范围内的小数,已经四舍五入到三位小数,求四舍五入到两位小数时失去的精度和
思路:因为范围过大,直接乘1000会爆,用字符串读入,只保留小数点后的。
代码:
#include <bits/stdc++.h>
using namespace std;
int n;
char s[55];
int main(){
while(~scanf("%d",&n)){
int ans=0;
while(n--){
scanf("%s",s);
int len=strlen(s);
int flag=0;
for(int i=0;i<len;i++){
if(s[i]=='.'){
flag=i;
break;
}
}
int ss=0;
for(int i=flag+1;i<len;i++){
ss=ss*10+s[i]-'0';
}
if(ss>=995) ans+=1000-ss;
else{
int tmp=ss%10;
if(tmp>=5) ans+=10-tmp;
else ans-=tmp;
}
}
printf("%.3f\n",(double)ans/1000.0);
}
return 0;
}
1010 Worker (HDOJ 6576)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6576
题意:给出n个工厂m个工人,每个工厂中每个人的产出为ai,要求每个工厂的总产出都相等,求问分配工人的方案
思路:要使得每个工厂的总产出相等,相当于求每个工厂单人产出的最小公倍数,求出为了达到最小公倍数每个工厂最少要安排多少人k,判断总工人数是否是k的倍数。m的范围不是1018而是1e18
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2020;
int n;
ll a[maxn],b[maxn],m;
int cnt[15];
int main(){
while(~scanf("%d%lld",&n,&m)){
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
cnt[a[i]]=1;
}
int flag,tmp;
ll sum;
for(int i=1;i<=10;i++){
if(cnt[i]!=0){
flag=i;
sum=i;
break;
}
}
tmp=flag;
for(int i=flag+1;i<=10;i++){
if(cnt[i]==0) continue;
tmp=__gcd(sum,(ll)i);
sum=sum*i/tmp;
}
// cout<<sum<<endl;
ll kk=0;
for(int i=1;i<=n;i++){
b[i]=sum/a[i];
kk+=b[i];
}
if(m%kk==0){
ll tot=m/kk;
printf("Yes\n");
for(int i=1;i<n;i++){
printf("%lld ",b[i]*tot);
}
printf("%lld\n",b[n]*tot);
}
else{
printf("No\n");
}
}
return 0;
}
1011 Class (HDOJ 6577)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6577
代码:
#include <bits/stdc++.h>
using namespace std;
int x,y;
int main(){
scanf("%d%d",&x,&y);
int a=(x+y)/2,b=(x-y)/2;
printf("%d\n",a*b);
return 0;
}