只做了三道题,rank1100+,居然上了1分。。。分数太低了。。。
A:给你n个字母,挑m个不连续、不相同的字母,看能不能挑出来a——z权值为1——26,能挑出来就输出挑出来的总权值。
代码:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=200010;
int n,m,k;
int a[maxn],sum[maxn];
int c[maxn];
int ans,ct,cnt,tmp,flag;
char s[maxn];
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
scanf("%s",s);
ans=0; flag=1;
memset(c,0,sizeof(c));
int l=strlen(s);
for(int i=0;i<l;i++){
a[i]=s[i]-'a'+1;
}
sort(a,a+n);
int ans=a[0];
flag=a[0];
int k=1;
if(m==k){printf("%d\n",ans);continue;}
for(int i=1;i<l;i++)
if(a[i]-flag>1){
ans+=a[i];
k++;
if(m==k) break;
flag=a[i];
}
if(k<m) puts("-1");
else printf("%d\n",ans);
// if(flag) puts("Yes"); else puts("No");
}
return 0;
}
B:就是有n个人,m个食物。每个食物属于第a[i]类,每个人只能吃同类别的食物,一天吃一个,求最多可以吃多少天。
没看数据范围,上来就二分,还傻乎乎的用优先队列了。。。其实 n m a[i] 范围都是100以内,直接暴力就行了。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
const int INF=0x3f3f3f3f;
int n,m;
int a[110];
struct poin
{
int w,id;
}mp[110];
int cmp(poin a,poin b)
{
return a.w>b.w;
}
vector<int>G;
int main()
{
scanf("%d%d",&n,&m);
int ans=0;
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i]);
if(!mp[a[i]].id)
{
mp[a[i]].id=a[i];
mp[a[i]].w++;
ans++;
}
else
{
mp[a[i]].w++;
}
}
sort(mp+1,mp+101,cmp);
int sum=0;
for(int i=1;i<=100;i++)
{
int cnt=0;
for(int j=1;j<=m;j++)
{
cnt+=mp[j].w/i;
}
//cout<<i<<" "<<cnt<<endl;
if(cnt<n)break;
sum=i;
}
cout<<sum<<endl;
return 0;
}
C:给你n个星球,火箭重m吨。给你每个星球的起飞系数a[i]和降落系数b[i]。让你从第一个星球到第n个星球结束最少耗费多少燃料。每到达一个星球,消耗的燃料为(m+此时火箭的燃料重量)/b[i] 。a[i]同理。。。
只需要倒着推,假设最终正好剩余0燃料,那么最后一次起飞消耗的燃料x满足(x+m)/a[n]=x 移项即可得倒推公式。b[i]也一样。
但是这里有个问题:倒着推的话应该先起飞再降落,也就是先a[i]再b[i],我代码里写倒了居然也过了,没挂终测,可能真的与顺序无关?
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=20010;
const long double eps=1e-12;
long double n,m,k;
long double a[maxn],b[maxn],sum[maxn];
long double ans,ct,cnt,tmp,flag;
char s[maxn];
int main()
{
while(cin>>n>>m)
{
flag=1;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
cin>>b[i];
}
int i=n-1;
long double x=0,y=0,ans=1.0;
while(i>=0)
{
if(a[i]==1||b[i]==1) ans=-1.0;
y=(m+x)/(b[i]-1.0);
x+=y;
y=(m+x)/(a[i]-1.0);
x+=y;
i--;
}
if(ans<0) puts("-1");
else cout<<fixed<<setprecision(12)<<x<<endl;
// if(flag) puts("Yes"); else puts("No");
}
return 0;
}
D:这个互动题真是坑。。。第一次见。。。出了个ILE错误。。。有待研究。。。
代码:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=20010;
int n,m,k,ans;
int a[maxn];
int main()
{
scanf("%d%d",&m,&n);
{
int flag=1;
for(int i=0;i<n;i++)
{
printf("%d\n",i+1);
fflush(stdout);
scanf("%d",&k);
if(k==1) a[i]=-1;
else if(k==-1)a[i]=1;
if(k==0) return 0;
}
int l=n,r=m;
int stp=0;
while(l<=r)
{
int mid=(l+r)>>1;
printf("%d\n",mid);
fflush(stdout);
scanf("%d",&k);
if(k==0)return 0;
k*=a[stp];
stp=(stp+1)%n;
if(k==-1)l=mid+1;
else r=mid;
}
//cout<<fixed<<setprecision(12)<<x<<endl;
// if(flag) puts("Yes"); else puts("No");
}
return 0;
}
E:给你n种纸币,求这n种纸币的任意组合mod m意义下,能组成多少0~m-1的数。
这就是离散数学的基本知识啊。。。n个纸币和m的gcd就是最小生成元,这个元的所有倍数小于m的数就是能生成的数。。。
代码:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=20010;
const long double eps=1e-12;
int n,m,k,ans;
int a;
int gcd(int x,int y)
{return y==0?x:gcd(y,x%y);}
int main()
{
scanf("%d%d",&n,&m);
{
int flag=1;
ans=m;
for(int i=0;i<n;i++)
{scanf("%d",&a);
ans=gcd(ans,a);
}
printf("%d\n",m/ans);
for(int i=0;i<m;i+=ans)
printf("%d%c",i,i+ans<m?' ':'\n');
//cout<<fixed<<setprecision(12)<<x<<endl;
// if(flag) puts("Yes"); else puts("No");
}
return 0;
}