2018.10.02 练习赛

[T1 蒜头君当大厨]

题解:

显然差分约束,怕你看不出样例还疯狂暗示你= =

\(code\):

#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<ctype.h>
#define ll long long 
using namespace std;

char buf[1<<20],*p1,*p2;
inline char gc()
{
//	return getchar();
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}

template<typename T>
inline void read(T &x)
{
	char tt;
	bool flag=0;
	while(!isdigit(tt=gc())&&tt!='-');
	tt=='-'?(flag=1,x=0):(x=tt-'0');
	while(isdigit(tt=gc())) x=x*10+tt-'0';
	if(flag) x=-x;
}

struct node{
	ll x,len;
	inline node(ll a=0,ll b=0)
	{
		x=a;
		len=b; 
	}
	inline bool operator<(node a)const
	{
		return len<a.len;
	}
};

queue<ll>q;
vector<node>G[20005];
ll n,m,dis[20005],tot[20005];
bool book[20005];

int spfa(int s) {
	for(int i=1; i<=n; i++) dis[i]=-1,book[i]=false;
	dis[s]=0,q.push(s),book[s]=true,tot[s]++;
	while (!q.empty()) {
		ll x=q.front();
		q.pop(),book[x]=false;
		if(tot[x]==n+1) return -1;
		for (int i=G[x].size()-1; i>=0; i--) {
			ll p=G[x][i].x;
			ll len=G[x][i].len;
			if(dis[p]>=dis[x]+len) continue;
			dis[p]=dis[x]+len;
			if(book[p]) continue;
			q.push(p),book[p]=true,tot[p]++;
		}
	}
	return 1;
}

int main()
{
	read(n),read(m);
	for(ll i=1;i<=n;i++)
	G[0].push_back(node(i,0));
	for(int i=1;i<=m;i++)
	{
		ll op,x,y,z;
		read(op);
		if(op<=2) read(x),read(y),read(z);
		if(op>=3) read(x),read(z);
		if(op==1) G[x].push_back(node(y,z));
		if(op==2) G[y].push_back(node(x,z));
		if(op==3) G[0].push_back(node(x,z));
		if(op==4) G[x].push_back(node(0,-z));
	}
	ll ans=0;
	if(spfa(0)==-1) puts("I can't"),exit(0);
	for(int i=1;i<=n;i++)
	ans=max(ans,dis[i]);
	printf("%lld",ans); 
}

[T2 上课]

题解:

贪心预处理出\(g[i]\),表示能力为\(i\)时最早的时刻为多少,然后就类似背包一样的\(DP\)

\(code:\)

#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<ctype.h>
#define ll long long
#define inf 1e9+9
using namespace std;

char buf[1<<20],*p1,*p2;
inline char gc()
{
//	return getchar();
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}

template<typename T>
inline void read(T &x)
{
	char tt;
	bool flag=0;
	while(!isdigit(tt=gc())&&tt!='-');
	tt=='-'?(flag=1,x=0):(x=tt-'0');
	while(isdigit(tt=gc())) x=x*10+tt-'0';
	if(flag) x=-x;
}

struct node{
	int t,len,x;
	inline node(int a=0,int b=0,int c=0)
	{
		t=a;
		len=b;
		x=c;
	}
	inline bool operator<(node a) const
	{
		return t<a.t;
	}
}a[1005];

int t,m,n;
int f[1005],g[105];
int main()
{
	read(t),read(m),read(n);
	for(int i=1;i<=m+1;i++) f[i]=-inf;
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		read(x),read(y),read(z);
		a[i]=node(x,y,z);
	}
	
	a[0].x=1,a[0].len=0,a[0].t=1,a[m+1].t=t+1;
	sort(a+1,a+1+m);
	
	for(int i=0;i<=100;i++) g[i]=inf;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		read(x),read(y);
		g[y]=min(g[y],x);
	}
	
	for(int i=1;i<=100;i++) g[i]=min(g[i],g[i-1]);
    
	for(int i=1;i<=m+1;i++)
    for(int j=0;j<i;j++)
    f[i]=max(f[i],f[j]+(a[i].t-(a[j].t+a[j].len))/g[a[j].x]);
	
	printf("%d",f[m+1]);
}

[T3 营救]

题解:

说实话思路很简单,但是但代码实现能力对我来说是硬伤啊\(......\)正解\(BFS+\)三进制状压\(DP\),略恶心

\(code:\)

#include<stdio.h>
#include<iostream> 
#include<math.h>
#include<string.h> 
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define inf 1e9+9
using namespace std;

struct point{
	int x,y;
	inline point(int a=0,int b=0)
	{
		x=a;
		y=b;
	}
}start,end_;


struct node{
	int x,y,s;
	inline node(int a=0,int b=0,int c=0)
	{
		x=a;
		y=b;
		s=c;
	}
	inline node(point a,int b=0)
	{
		x=a.x;
		y=a.y;
		s=b;
	} 
};

int n,m,k,ans=inf,tot;
int val[11];
char a[11][11],ss[11];
int f[200005][11][11];
int s[20];
queue<node>q;
int quanji;
int calspd(int num)
{
	int len=0,sum=k;
	memset(s,0,sizeof(s));
	while(num)
	{
		s[++len]=num%3;
		num/=3;
	}
	for(int i=1;i<=tot;i++)
	sum+=(s[i]==1)?val[i]:0;
	return sum<1?1:sum;
}

int merge(int num,int x,int y)
{
	int len=0,sum=0;
	memset(s,0,sizeof(s));
	while(num)
	{
		s[++len]=num%3;
		num/=3;
	}
	int flag=0;
	for(int i=1;i<=tot;i++)
	if(ss[i]==a[x][y]) flag=i;
	if(s[flag]) return 0;
	s[flag]=1;
	for(int i=tot;i>=1;i--)
	sum=sum*3+s[i];
	return sum;
}

int drop1(int num)//放下减速的 
{
	int len=0,sum=0;
	memset(s,0,sizeof(s));
	while(num)
	{
		s[++len]=num%3;
		num/=3;
	}
	for(int i=1;i<=tot;i++)
	if(s[i]==1&&val[i]>0) s[i]=2;
	for(int i=tot;i>=1;i--)
	sum=sum*3+s[i];
	return sum;
}

int drop2(int num)//全放下 
{
	int len=0,sum=0;
	memset(s,0,sizeof(s));
	while(num)
	{
		s[++len]=num%3;
		num/=3;
	}
	for(int i=1;i<=tot;i++)
	if(s[i]) s[i]=2;
	for(int i=tot;i>=1;i--)
	sum=sum*3+s[i];
	return sum;
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		char tt; 
		scanf("\n%c",&tt);
		if(tt=='s') start=point(i,j);
		if(tt=='#') a[i][j]='#';
		if(tt=='t') end_=point(i,j);
		if(tt>='A'&&tt<='Z') a[i][j]=tt,tot++;
	}
	quanji=pow(3,tot)-1;
	for(int i=1;i<=tot;i++)
	{
		char tt;
		int x;
		scanf("\n%c%d",&tt,&x);
		ss[i]=tt;
		val[tt-'A'+1]=x;
	}
//	printf("%d %d %d",drop1(3),drop2(3),merge(3,3,3));
	
	for(int i=0;i<=quanji;i++)
	for(int j=1;j<=10;j++)
	for(int z=1;z<=10;z++)
	f[i][j][z]=inf;
	f[0][start.x][start.y]=0;
	
	q.push(node(start,0));
	while(!q.empty())
	{
		int tx=q.front().x,ty=q.front().y,ts=q.front().s;
		q.pop();
		int spd=calspd(ts);
		if(tx+1<=n&&a[tx+1][ty]!='#'&&f[ts][tx+1][ty]>f[ts][tx][ty]+spd)//下 
		{
			f[ts][tx+1][ty]=f[ts][tx][ty]+spd; 
			q.push(node(tx+1,ty,ts));
		}
		if(ty+1<=m&&a[tx][ty+1]!='#'&&f[ts][tx][ty+1]>f[ts][tx][ty]+spd)//右
		{
			f[ts][tx][ty+1]=f[ts][tx][ty]+spd;
			q.push(node(tx,ty+1,ts));
		} 
		if(tx-1>0&&a[tx-1][ty]!='#'&&f[ts][tx-1][ty]>f[ts][tx][ty]+spd)//上 
		{
			f[ts][tx-1][ty]=f[ts][tx][ty]+spd;
			q.push(node(tx-1,ty,ts));
		} 
		if(ty-1>0&&a[tx][ty-1]!='#'&&f[ts][tx][ty-1]>f[ts][tx][ty]+spd)//左
		{
			f[ts][tx][ty-1]=f[ts][tx][ty]+spd;
			q.push(node(tx,ty-1,ts));
		} 
		if(a[tx][ty]>='A'&&a[tx][ty]<='Z')//合并
		{
			int newset=merge(ts,tx,ty);
			if(!newset||f[newset][tx][ty]<=f[ts][tx][ty]) continue;
			f[newset][tx][ty]=f[ts][tx][ty];
			q.push(node(tx,ty,newset));
		} 
		if(tx==end_.x&&ty==end_.y)//放下
		{
			int new1=drop1(ts),new2=drop2(ts);
			if(f[new1][tx][ty]>f[ts][tx][ty])
			{
				f[new1][tx][ty]=f[ts][tx][ty];
				q.push(node(tx,ty,new1));
			}
			
			if(f[new2][tx][ty]>f[ts][tx][ty])
			{
				f[new2][tx][ty]=f[ts][tx][ty];
				q.push(node(tx,ty,new2));
			}
		} 
	}
	printf("%d",f[quanji][end_.x][end_.y]);
}
posted @ 2018-10-02 22:41  Katoumegumi  阅读(66)  评论(0编辑  收藏  举报
返回顶部