20181008

T1

奶牛Bessie潜入了农夫约翰的家,她发现这里有无穷无尽的柠檬派和橘子派。

Bessie的饱胀值一开始是0,且上限是T,每个柠檬派可以提供A点饱胀值,每个橘子派可以提供B点饱胀值。

Bessie可以不断地吃东西,如果她的饱胀值没有超出T的话。同时,Bessie有一次喝水的机会,喝完后,她的饱胀值将减少一半(往下取整)。

请计算出Bessie的饱胀值最多可以达到多少。

输入格式

只有一行,分别是T (1≤T≤5,000,000), A, and B (1≤A,B≤T).

输出格式

一个整数表示bessie能够达到的最大饱胀值。

输入样例

8 5 6

输出样例

考试代码 :58

#include<bits/stdc++.h>
using namespace std;
#define ll long long
void FRE(){freopen("fruit.in","r",stdin);freopen("fruit.out","w",stdout);}
void FCL(){fclose(stdin);fclose(stdout);}
inline ll rd()
{
	ll x=0,ert=1;char lk=getchar();
	while(!isdigit(lk)){if(lk=='-') ert=-1;lk=getchar();}
	while(isdigit(lk)){x=(x<<3)+(x<<1)+(lk-'0');lk=getchar();}
	return x*ert;
}
const int N=5e6+10;
bool f[N];
int main()
{
	FRE();
	int n=rd(),a=rd(),b=rd(),ans=0;
	f[a]=f[b]=1;int i=max(a,b)+1;
	for(;i<=n;i++) 
	{
		f[i]=f[i-a]||f[i-b];
		if(f[i]) ans=i;
	}
	int j=n;i=max(a,b);
	for(;i<=n;i++)
	{
		if(!f[i]) continue;
		int p=i>>1;
		if((n-p)<j) j=n-p;
		while(!f[j]&&j>0) j--;
		if((p+j)>ans) ans=p+j;
	}
	printf("%d",ans);
	FCL();
	return 0;
}

 AC

#include<bits/stdc++.h>
using namespace std;
#define ll long long
void FRE(){freopen("fruit.in","r",stdin);freopen("fruit.out","w",stdout);}
void FCL(){fclose(stdin);fclose(stdout);}
inline ll rd()
{
	ll x=0,ert=1;char lk=getchar();
	while(!isdigit(lk)){if(lk=='-') ert=-1;lk=getchar();}
	while(isdigit(lk)){x=(x<<3)+(x<<1)+(lk-'0');lk=getchar();}
	return x*ert;
}
const int N=5e6+10;
bool f[N][2];
int main()
{
	//FRE();
	int n=rd(),a=rd(),b=rd(),ans=0;
	f[0][0]=1;
	for(int i=1;i<=n;i++) 
	{
		if(i>=a) f[i][0]|=f[i-a][0];
		if(i>=b) f[i][0]|=f[i-b][0];
		if(f[i][0]) 
		{
			f[(i/2)+a][1]=1;
			f[(i/2)+b][1]=1;
			ans=i;
		}
	}
	for(int i=0;i<=n;i++)
	{
		if(f[i][1]) f[i+a][1]=1,f[i+b][1]=1;
		if(f[i][1]) ans=max(ans,i);
	}
	printf("%d",ans);
	//FCL();
	return 0;
}

 

T2

贝西很喜欢玩一种纸牌游戏。

贝西和她的朋友艾尔西正在玩这个简单的纸牌游戏。游戏有2N张牌,牌上的数字是1到2N。把这些牌分成两份,贝西有N张,艾尔西有另外N张。接下来她们进行N轮出牌,每次各出一张牌。一开始,谁出的牌上的数字大,谁就获得这一轮的胜利。贝西有一个特殊权利,她可以在任意一个时刻把原本数字大的获胜的规则改成数字小的获胜,这个改变将会一直持续到游戏结束。特别的,贝西可以从第一轮开始就使用小牌获胜的规则,也可以直到最后一轮都还杂使用大牌获胜的规则。

现在,贝西已经知道了艾尔西出牌的顺序,她想知道她最多能够赢多少轮。

输入格式:

第一行包含一个整数 N (2≤N≤50,000).

接下来N行表示艾尔的出牌顺序。

输出格式:

一个整数表示贝西最多能赢多少轮。

输入样例

4

1

8

4

3

输出样例

3

考试AC

#include<bits/stdc++.h>
using namespace std;
#define ll long long
void FRE(){freopen("cardgame.in","r",stdin);freopen("cardgame.out","w",stdout);}
void FCL(){fclose(stdin);fclose(stdout);}
inline ll rd()
{
	ll x=0,ert=1;char lk=getchar();
	while(!isdigit(lk)){if(lk=='-') ert=-1;lk=getchar();}
	while(isdigit(lk)){x=(x<<3)+(x<<1)+(lk-'0');lk=getchar();}
	return x*ert;
}
const int N=1e5+10,inf=1e9;
int val[N],ra[N],ls[N],rs[N],cnt,rt,a[N],b[N],f[N],g[N];
bool v[N];
void ltu(int &p){int t=ls[p];ls[p]=rs[t];rs[t]=p;p=t;}
void rtu(int &p){int t=rs[p];rs[p]=ls[t];ls[t]=p;p=t;}
void ins(int &p,int x)
{
	if(!p){val[p=++cnt]=x,ra[p]=rand();return ;}
	if(val[p]==x) return ;
	if(x<val[p])
	{
		ins(ls[p],x);
		if(ra[ls[p]]<ra[p]) ltu(p);
	}
	else
	{
		ins(rs[p],x);
		if(ra[rs[p]]<ra[p]) rtu(p);
	}
}
void del(int &p,int x)
{
	if(!p) return ;
	if(val[p]==x)
	{
		if(!ls[p]||!rs[p]) p=ls[p]+rs[p];
		else if(ra[ls[p]]<ra[rs[p]]) ltu(p),del(p,x);
		else rtu(p),del(p,x);
	}
	x<val[p]?del(ls[p],x):del(rs[p],x);
}
int qq(int p,int x)
{
	if(!p) return -inf;
	return val[p]<x?max(val[p],qq(rs[p],x)):qq(ls[p],x);
}
int hj(int p,int x)
{
	if(!p) return inf;
	return val[p]>x?min(val[p],hj(ls[p],x)):hj(rs[p],x);
}
int main()
{
	FRE();
	int n=rd(),cn=0,ans=0;
	for(int i=1;i<=n;i++) a[i]=rd(),v[a[i]]=1;
	for(int i=1;i<=(n<<1);i++) if(!v[i]) b[++cn]=i,ins(rt,i);
	for(int i=1;i<=n;i++)
	{
		f[i]=f[i-1];
		int x=hj(rt,a[i]);
		if(x==inf) continue;
		f[i]++;del(rt,x);
	}
	rt=0;cnt=0;
	memset(val,0,sizeof(val));
	memset(ls,0,sizeof(ls));
	memset(rs,0,sizeof(rs));
	memset(ra,0,sizeof(ra));
	for(int i=1;i<=n;i++) ins(rt,b[i]);
	for(int i=n;i>0;i--)
	{
		g[i]=g[i+1];
		int x=qq(rt,a[i]);
		if(x==-inf) continue;
		g[i]++;del(rt,x);
	}
	for(int i=0;i<=n;i++) ans=max(ans,f[i]+g[i+1]);
	printf("%d",ans);
 	FCL();
	return 0;
}

 

T3

T 城是一个旅游城市,具有n个景点和m条道路,所有景点编号为 1,2,...,n。每条道路连接这n个景区中的某两个景区,道路是单向通行的。每条道路都有一个长度。

为了方便旅游,每个景点都有一个加油站。第i个景点的加油站的费用为 pip_ipi,加油量为ci 。若汽车在第 i个景点加油,则需要花费pi元钱,之后车的油量将被加至油量上限与ci中的较小值。不过如果加油前汽车油量已经不小于ci,则不能在该景点加油。

C 准备来到 T 城旅游。他的汽车油量上限为 C。旅游开始时,汽车的油量为 0。在旅游过程中:

1、当汽车油量大于0时,汽车可以沿从当前景区出发的任意一条道路到达另一个景点(不能只走道路的一部分),汽车油量将减少1;

2、当汽车在景点i且当前油量小于ci时,汽车可以在当前景点加油,加油需花费pi元钱,这样汽车油量将变为min{ci,C}。

一次旅游的总花费等于每次加油的花费之和,旅游的总路程等于每次经过道路的长度之和。注意多次在同一景点加油,费用也要计算多次,同样地,多次经过同一条道路,路程也要计算多次。

C 计划旅游T次,每次旅游前,小 C 都指定了该次旅游的起点和目标路程。由于行程不同,每次出发前带的钱也不同。为了省钱,小 C 需要在旅游前先规划好旅游路线(包括旅游的路径和加油的方案),使得从起点出发,按照该旅游路线旅游结束后总路程不小于目标路程,且剩下的钱尽可能多。请你规划最优旅游路线,计算这T次旅游每次结束后最多可以剩下多少钱。

输入格式

输入第一行包含四个正整数 n,m,C,T,每两个整数之间用一个空格隔开,分别表示景点数、道路数、汽车油量上限和旅行次数。

接下来 n 行,每行包含两个正整数 pi ,ci,每两个整数之间用一个空格隔开,按编号顺序依次表示编号为 1,2,...,n 的景点的费用和油量。

接下来 m 行,每行包含三个正整数 ai,bi,li,每两个整数之间用一个空格隔开,表示一条从编号为ai的景点到编号为bi 的景点的道路,道路的长度为li。保证 ai≠bi,但从一个景点到另一个景点可能有多条道路。

最后 T 行,每行包含三个正整数si,qi,di,描述一次旅游计划,旅游的起点为编号为si的景点,出发时带了qi元钱,目标路程为di。

输出格式

输出 T行,每行一个整数,第 iii 行的整数表示第 i次旅游结束后最多剩下多少元钱。如果旅游无法完成,也就是说不存在从景点 si出发用不超过 qi元钱经过不小于 di的路程的路线,则该行输出 −1。

样例输入

6 6 3 2

4 1

6 2

2 1

8 1

5 4

9 1

1 2 1

1 3 1

2 4 1

3 5 1

4 6 1

5 6 1

1 12 3

1 9 3

样例输出

2

-1 

考试 40

#include<bits/stdc++.h>
using namespace std;
#define ll long long
void FRE(){freopen("tour.in","r",stdin);freopen("tour.out","w",stdout);}
void FCL(){fclose(stdin);fclose(stdout);}
inline ll rd()
{
	ll x=0,ert=1;char lk=getchar();
	while(!isdigit(lk)){if(lk=='-') ert=-1;lk=getchar();}
	while(isdigit(lk)){x=(x<<3)+(x<<1)+(lk-'0');lk=getchar();}
	return x*ert;
}
const int N=1e2+10,inf=1e9;
struct zx{int nx,to,v;}e[N*10];
int h[N],p[N],c[N],C,d,ans,nm,f[N][N];
void dfs(int sum,int y,int mey,int x)
{
	if(mey<=ans) return ;
	if(sum>=d){ans=mey;return ;}
	for(int i=h[x];i;i=e[i].nx)
	{
		int w=e[i].to;
		if(y>0) dfs(sum+e[i].v,y-1,mey,w);
		if(mey>=p[x]&&y<c[x]) dfs(sum+e[i].v,min(c[x],C)-1,mey-p[x],w);
	}
}
void add(int x,int y,int w){e[++nm].nx=h[x];e[nm].to=y;h[x]=nm;e[nm].v=w;}
int main()
{
	FRE();
	int n=rd(),m=rd();C=rd();int T=rd(),x,y;
	for(int i=1;i<=n;i++) p[i]=rd(),c[i]=rd();
	for(int i=1;i<=m;i++) {x=rd(),y=rd();f[x][y]=max(f[x][y],(int)rd());}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(f[i][j]) add(i,j,f[i][j]);
	for(int i=1;i<=T;i++)
	{
		x=rd(),y=rd(),d=rd();ans=-1;
		dfs(0,0,y,x);
		printf("%d\n",ans);
	}
 	FCL();
	return 0;
}

  

posted @ 2018-10-08 20:03  西白方丈  阅读(160)  评论(0编辑  收藏  举报