这次网络赛我共出了三题,现给出题解
自动售货机
由于测试样例很多,每次都计算会超时,所以要打表,递推方程为dp[i][j]=dp[i-1][j]+dp[i-1][j-1];注意优化剪枝,在dp循环过程中如果不剪枝,实打实的2000*1000也是会超时的。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
using namespace std;
int dp[2005][1005];
const int mod=(1e9+7);
int main()
{
//freopen("in3.txt","r",stdin);
//freopen("out3.txt","w",stdout);
dp[1][0]=1;
for(int i=2;i<=2000;i++)
{
dp[i][0]=1;
int len=i/2;
for(int j=1;j<=len;j++)
{
dp[i][j]=(dp[i-1][j]+dp[i-1][j-1]);
if(dp[i][j]>=mod)
dp[i][j]%=mod;
}
}
int n,m;
while(~scanf("%d%d",&n,&m))
{
printf("%d\n",dp[n+m][m]);
}
return 0;
}
KSS金牌梦1
map离散化+变化的拓扑排序,时限比较紧,实在没想到OJ运行速度如此慢,本机上1s不到,我的锅。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
const int MAXN=505;
int g[MAXN][MAXN],in[MAXN];
bool vis[MAXN];
int main()
{
//freopen("in1.txt","r",stdin);
int n,m,cnt;
while(~scanf("%d",&n))
{
map<string,int> mp;
cnt=1;
memset(g,0,sizeof(g));
memset(in,0,sizeof(in));
memset(vis,false,sizeof(vis));
while(n--)
{
char a[50],b[50];
//string a,b;
scanf("%s%s",a,b);
if(mp[a]==0)mp[a]=cnt++;
if(mp[b]==0)mp[b]=cnt++;
g[mp[b]][mp[a]]=1;
in[mp[a]]++;//cout<<n<<endl;
}
bool flag=false;
for(int i=1;i<cnt;i++)
{
for(int j=1;j<cnt;j++)
{
if(in[j]==0 && !vis[j])
{
vis[j]=1;
flag=true;
for(int k=1;k<cnt;k++)
if(g[j][k])
in[k]--;
break;
}
}
if(flag==false)
break;
flag=false;
}
scanf("%d",&m);
int num=0;
for(int i=0;i<m;i++)
{
string a;
cin>>a;
if(mp[a]>0 && vis[mp[a]]) num++;
}
if(1.0*num/m>0.7)
cout<<"Excelsior!"<<endl;
else
cout<<"KSS have a dream!"<<endl;
}
return 0;
}
离线存储,按距离排序,加入主席树,维护区间和与覆盖次数两个属性,二分位置查询得出结果,WA点很多很多很多很多,又是我的锅。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<time.h>
using namespace std;
const int MAXN=100005;
struct node
{
int l,d,val,flag;
}in[MAXN<<1];
struct node1
{
int x,a,b,c;
}in2[MAXN];
struct tree
{
int l,r,cnt,flag[2];
long long val;
}tree[MAXN*35];
int root[MAXN<<1],pos;
bool cmp1(node a,node b)
{
return a.d<b.d;
}
bool cmp2(node a,node b)
{
return a.l<b.l;
}
void pushup(int now)
{
tree[now].cnt=0;
tree[now].val=0;
if(tree[now].flag[0]!=-1)
{
tree[now].cnt+=tree[tree[now].flag[0]].cnt;
tree[now].val+=tree[tree[now].flag[0]].val;
}
if(tree[now].flag[1]!=-1)
{
tree[now].cnt+=tree[tree[now].flag[1]].cnt;
tree[now].val+=tree[tree[now].flag[1]].val;
}
}
int build(int l,int r)
{
int now=pos++;
tree[now].l=l;
tree[now].r=r;
tree[now].cnt=tree[now].val=0;
tree[now].flag[0]=tree[now].flag[1]=-1;
if(l==r)
return now;
int mid=(l+r)>>1;
tree[now].flag[0]=build(l,mid);
tree[now].flag[1]=build(mid+1,r);
return now;
}
int update(int l,int r,int v,int v1,int pre,int flag)
{
int now=pos++;
tree[now].l=l;
tree[now].r=r;
tree[now].flag[0]=tree[pre].flag[0];
tree[now].flag[1]=tree[pre].flag[1];
tree[now].cnt=tree[pre].cnt;
tree[now].val=tree[pre].val;
if(l==r)
{
if(flag)
{
tree[now].cnt--;
tree[now].val-=v1;
}
else
{
tree[now].cnt++;
tree[now].val+=v1;
}
return now;
}
int mid=(l+r)>>1;
if(v<=mid)
tree[now].flag[0]=update(l,mid,v,v1,tree[pre].flag[0],flag);
else
tree[now].flag[1]=update(mid+1,r,v,v1,tree[pre].flag[1],flag);
pushup(now);
return now;
}
long long query(int l,int r,int now,long long k)
{
if(l==r)
{
if(tree[now].cnt==0)
return 0;
return tree[now].val/tree[now].cnt*k;
}
int mid=(l+r)>>1;
long long ans=0;
if(k<=tree[tree[now].flag[0]].cnt)
ans+=query(l,mid,tree[now].flag[0],k);
else
ans+=tree[tree[now].flag[0]].val+query(mid+1,r,tree[now].flag[1],k-=tree[tree[now].flag[0]].cnt);
return ans;
}
int main()
{
//freopen("in2.txt","r",stdin);
//freopen("out2.txt","w",stdout);
int n,m,x,p;
while(~scanf("%d%d%d%d",&n,&m,&x,&p))
{
long long prescore=1;
pos=0;
int l,r,d,num=1;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&l,&r,&d);
in[num].l=l;
in[num].d=d;
in[num++].flag=0;
in[num].l=r+1;
in[num].d=d;
in[num++].flag=1;
}
for(int i=0;i<m;i++)
scanf("%d%d%d%d",&in2[i].x,&in2[i].a,&in2[i].b,&in2[i].c);
sort(in+1,in+num,cmp1);
int cnt=0;
in[num].d=-1;
for(int i=1;i<num;i++)
if(in[i].d!=in[i+1].d)
in[i].val=cnt++;
else
in[i].val=cnt;
sort(in+1,in+num,cmp2);
root[0]=build(0,cnt-1);
for(int i=1;i<num;i++)
root[i]=update(0,cnt-1,in[i].val,in[i].d,root[i-1],in[i].flag);
for(int i=0;i<m;i++)
{
int low=1,high=n*2;
int ans1=0;
while(low<=high)
{
int mid=(low+high)>>1;
if(in[mid].l<=in2[i].x)
{
ans1=mid;
low=mid+1;
}
else
high=mid-1;
}
long long nowk=((long long)in2[i].a*prescore+(long long)in2[i].b)%(long long)in2[i].c;
int flag=0;
if(prescore>p)
flag=1;
if(ans1)
{
if(nowk>=tree[root[ans1]].cnt)
{
prescore=(tree[root[ans1]].val);
if(flag)
prescore*=2;
}
else
{
prescore=query(0,cnt-1,root[ans1],nowk);
if(flag)
prescore*=2;
}
}
else
prescore=0;
printf("%I64d\n",prescore);
}
}
return 0;
}