版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
A
这种题目,写个Trie随便切。
#include<cstdio>
#include<cstring>
#define N 110
#define NN 11000
using namespace std;
struct node
{
int a[30],id;
}tr[NN];int len=1;
void add(char ss[],int id)
{
int ed=strlen(ss+1),x=1;
for(int i=1;i<=ed;i++)
{
if(!tr[x].a[ss[i]-'a'])tr[x].a[ss[i]-'a']=++len;
x=tr[x].a[ss[i]-'a'];
}
tr[x].id=id;
}
int find(char ss[])
{
int ed=strlen(ss+1),x=1;
for(int i=1;i<=ed;i++)x=tr[x].a[ss[i]-'a'];
return tr[x].id;
}
char st[N][N],ss[5][N];
int n,m;
inline bool check(int x,int y)
{
if(strlen(st[x]+1)!=strlen(ss[y]+1))return false;
for(int i=strlen(st[x]+1);i>=1;i--)
{
if(st[x][i]!=ss[y][i])return false;
}
return true;
}
char ans[]={'A','B','C','D'};
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",ss[0]+1);
add(ss[0],i);
scanf("%s",st[i]+1);
}
for(int i=1;i<=m;i++)
{
scanf("%s%s%s%s%s",ss[0]+1,ss[1]+1,ss[2]+1,ss[3]+1,ss[4]+1);
int x=find(ss[0]);
for(int j=1;j<=4;j++)
{
if(check(x,j)==true)
{
printf("%c\n",ans[j-1]);
break;
}
}
}
return 0;
}
B
以为很难,发现其实就是贪心,对于吃 种食品,那么满足感最大的肯定是最大的前 种食品啦。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define N 310000
using namespace std;
int n,a[N];
double ans=0;
inline bool cmp(int x,int y){return x>y;}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+n+1,cmp);
long long x=0;
for(int i=1;i<=n;i++)
{
x+=a[i];
ans=max(x*1.0/i*x,ans);
}
printf("%lf\n",ans);
return 0;
}
C
比较简单的贪心。
对于自己获得最多的方案,就是优先编号小的。
那么是不是对于亏的少的,是不是就是一直跑编号大的?
不不不,对于这个图,这种做法就会走上我们的“星光大道”,直接WA声一片。还是有46pts
那么正确的贪心思想是什么呢。
我们想,如果现在就是走一个小数字,然后走一个特大数字,花费为 ,那么如果我先走目前最大的数字,把小数字免了,然后再走特大数字,是不是也是 ,很明显,后者在多数情况会更优。
那么贪心策略出来了。
对于目前的编号最大值,我们把所有能走的编号小于最大值的点都走了,直到不能走,那么再走现在能走的点钟编号最大的,然后继续重复此过程。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define N 510000
using namespace std;
priority_queue<int>q1;
priority_queue<int,vector<int>,greater<int> >q2;
struct node
{
int y,next;
}a[N];int len,last[N];
inline void ins(int x,int y){len++;a[len].y=y;a[len].next=last[x];last[x]=len;}
int n,m,in1[N],in2[N];
void findans1()
{
for(int i=1;i<=n;i++)
{
if(!in1[i])q2.push(i);
}
int mmax=0,T=n-1,ans=0;
while(T--)
{
int x=q2.top();q2.pop();
if(x>mmax)ans++,mmax=x;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;in1[y]--;
if(!in1[y])q2.push(y);
}
}
if(q2.top()>mmax)ans++;
printf("%d\n",ans);
}
int sta[N],tail;
void findans2()
{
for(int i=1;i<=n;i++)
{
if(!in2[i])q1.push(i);
}
int mmax=0,T=n,ans=0;
while(T)
{
int x=q1.top();q1.pop();
mmax=x;ans++;sta[tail=1]=x;
while(!q1.empty())sta[++tail]=q1.top(),q1.pop();
while(tail)
{
T--;
int y=sta[tail--];
for(int k=last[y];k;k=a[k].next)
{
int z=a[k].y;in2[z]--;
if(!in2[z])
{
if(z>mmax)q1.push(z);
else sta[++tail]=z;//能走我的点
}
}
}
}
printf("%d\n",ans);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;scanf("%d%d",&x,&y);
ins(x,y);in1[y]++;in2[y]++;
}
findans1();
findans2();
return 0;
}