Atcoder Beginner Contest 317

​​​​​​D - President (atcoder.jp)

题意:T和A票数比较,找出最小的使T胜利的从A转移到T 的票数,只要获得的转移票数>总的Z的一半即认为其胜利,

X为投给T的,Y为投给A的,Z为每一轮的T如果需要赢需要比A大Z。

解题:采用dp,dp[i]表示:获得z票数i的转移票数。如果该轮转移则需转移(x+y+1)/2-x票。

#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
using namespace std;

int main() {
  long long inf = 1e18;

  int N;
  cin >> N;
  long long z_sum=0;
  vector<int> X(N), Y(N), Z(N);
  for (int i = 0; i < N; i++) 
  {
  	cin >> X[i] >> Y[i] >> Z[i];
  	z_sum+=Z[i];
  }
  vector<long long> dp(z_sum + 1, inf);
  dp[0] = 0;
  for (int i = 0; i < N; i++) {
    int x = X[i], y = Y[i], z = Z[i];
    int w = max(0, (x + y) / 2 + 1 - x);
    for (int j = z_sum; j >= z; j--) {
      dp[j] = min(dp[j], dp[j - z] + w);
    }
  }
  long long ans = inf;
  for (int j = z_sum / 2 + 1; j <= z_sum; j++) ans = min(ans, dp[j]);
  cout << ans << endl;
}

E - Avoid Eye Contact (atcoder.jp)

首先筛选出不合适的,将所以不合适的都置为true,不可通过。

然后bfs找到最小通路。模板题。

#include<bits/stdc++.h>
using namespace std;
const int N=2101;
bool st[N][N];
char g[N][N];
int dist[N][N];
int n,m;
int ans=0;
typedef pair<int,int>PII;
int sx,sy,ex,ey;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void bfs()
{
	memset(dist,0x3f,sizeof(dist));
	queue<PII>q;
	q.push({sx,sy});
	dist[sx][sy]=0;
//	st[sx][sy]=true;
//	cout<<sx<<" "<<sy<<endl;
//cout<<q.front().first<<endl;
	while(!q.empty())
	{
		auto t=q.front();
		int x=t.first,y=t.second;
//		cout<<x<<" "<<y<<endl;
		q.pop();
		
		if(x==ex&&y==ey)
		return ;
		for(int i=0;i<4;i++)
		{
			int xx=x+dx[i],yy=y+dy[i];
//			if(st[xx][yy]=true||xx<1||xx>n||yy<1||yy>m)
//			continue;
//			if(dist[xx][yy]>dist[x][y]+1)
//			{
//				dist[xx][yy]=dist[x][y]+1;
//				q.push({xx,yy});
//			 } 
				if (xx>0&&xx<=n&&yy>0&&yy<=m&&st[xx][yy]!=true&&dist[xx][yy]>dist[x][y]+1)
			{
				dist[xx][yy]=dist[x][y]+1;
				q.push({xx,yy});
//				cout<<xx<<" "<<yy<<endl; 
			}
		}
	}
}
int main()
{
	cin>>n>>m;
//	memset(dist,0x3f,sizeof dist);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>g[i][j];
			if(g[i][j]=='S')
			sx=i,sy=j;
			if(g[i][j]=='G')
			ex=i,ey=j;
			if(g[i][j]=='^'||g[i][j]=='v'||g[i][j]=='>'||g[i][j]=='<'||g[i][j]=='#')
			st[i][j]=true;
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(g[i][j]=='v')
			{
				for(int k=i+1;k<=n;k++)
				{
					if(g[k][j]=='#'||g[k][j]=='<'||g[k][j]=='>'||g[k][j]=='v'||g[k][j]=='^')
					break;
					st[k][j]=true;
				}
			}
			else if(g[i][j]=='^')
			{
				for(int k=i-1;k>0;k--)
				{
					if(g[k][j]=='#'||g[k][j]=='<'||g[k][j]=='>'||g[k][j]=='v'||g[k][j]=='^')
					break;
					st[k][j]=true;
				}
			}
			else if(g[i][j]=='<')
			{
				for(int k=j-1;k>0;k--)
				{
					if(g[i][k]=='#'||g[i][k]=='<'||g[i][k]=='>'||g[i][k]=='v'||g[i][k]=='^')
					break;
					st[i][k]=true;
				}
			}
			else if(g[i][j]=='>')
			{
				for(int k=j+1;k<=m;k++)
				{
					if(g[i][k]=='#'||g[i][k]=='<'||g[i][k]=='>'||g[i][k]=='v'||g[i][k]=='^')
					break;
					st[i][k]=true;
				}
			}
		}
	}
//	cout<<bfs(sx,sy,ex,ey)<<endl;
bfs();
//cout<<ex<<" "<<ey<<endl;
//for(int i=1;i<=n;i++)
//{
//	for(int j=1;j<=m;j++)
//	cout<<dist[i][j]<<" ";
//	cout<<endl;
//}
	if(dist[ex][ey]==1061109567)
	cout<<"-1"<<endl;
	else
	cout<<dist[ex][ey]<<endl;
}

C - Remembering the Days (atcoder.jp)

经典dfs。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll ans=0,res=0;
ll n,t,m;
ll c[101];
const int N=220;
bool st[101];
ll e[N],h[N],ne[N],w[N],idx;
void add(ll a,ll b,ll v)
{
	e[idx]=b,w[idx]=v,ne[idx]=h[a],h[a]=idx++;
}
ll dfs(ll x,ll cnt)
{
	st[x]=true;
	ans=max(ans,cnt);
	for(int i=h[x];i!=-1;i=ne[i])
	{
		int y=e[i];
		if(st[y])continue;
		st[y]=true;
		dfs(y,cnt+w[i]);
		st[y]=false;
//		dfs(y,cnt);
	}
	ans=max(ans,cnt);
	return ans;
}
int main()
{
	cin>>n>>m;
	memset(h,-1,sizeof h);
	for(int i=1;i<=m;i++)
	{
		ll x,y,z;
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	ll res=0;
	for(int i=1;i<=n;i++)
	{
		memset(st,false,sizeof st);
//		dfs(i,w[i]);
		res=max(res,dfs(i,0));
	}
	cout<<res<<endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值