Atcoder abc251 题解 (A~G)

A . Six Characters (字符串)

循环输出字符串直到长度为6即可,没什么难的。

string s;
    cin>>s;
    int lens=s.size();
    for(int i=lens;i<=6;i+=lens)
      cout<<s;

B . At Most 3 (Judge ver.) (枚举)

题意:问给出的一组数中,少于等于3个数字的和,其中小于W的数有多少个。
因为N最多只有300,所以暴力枚举即可,注意有重复的,我们用set去重。

#include<bits/stdc++.h>
#define ll long long
//const int N=1e6+5;
//const int N=1e5+5;
//const int mod=1e9+7;
//const long long mod=998244353;
using namespace std;

int n,w,ans;

int a[305];
set<int>s;

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>w;
    for(int i=1;i<=n;++i)
      cin>>a[i];
    for(int i=1;i<=n;++i)
      {
      	int t=a[i];
        if(t<=w)
          if(!s.count(t))
          	{
          	    ++ans;
          	    s.insert(t);
          	}
      }
    for(int i=1;i<=n;++i)
      for(int j=i+1;j<=n;++j)
      {
      	int t=a[i]+a[j];
        if(t<=w)
          if(!s.count(t))
          	{
          	    ++ans;
          	    s.insert(t);
          	}
       }
    for(int i=1;i<=n;++i)
      for(int j=i+1;j<=n;++j)
        for(int k=j+1;k<=n;++k)
          {
          	int t=a[i]+a[j]+a[k];
          	if(t<=w)
          	  if(!s.count(t))
          	    {
          	    	++ans;
          	    	s.insert(t);
          	    }
          }
        printf("%d",ans);
}

C . Poem Online Judge (模拟)

题意:找出第一次出现时有最大分数的字符串。
还是用set去重,维护最大值对应的下标即可。

string k;
    set<string>s;
    cin>>n;
    for(int i=1;i<=n;++i)
      {
      	cin>>k>>a[i];
      	if(a[i]>a[maxn]&&!s.count(k))
      	  maxn=i;
      	s.insert(k);
      }
    printf("%d",maxn);

D . At Most 3 (Contestant ver.) (构造)

题意:构造一组数,使其能用三个不同数的和构造W以下的任何一个数。

我们首先可以想到二进制数可以构造任何一个数的特点,但是这里要求三个不同数,所以显然不可以。我们可以用199,1009900,10000~990000,297个数来满足题意,每次都输出这组数就可以了,不用管w的大小。

cin>>w;
    printf("297\n");
    for(int i=1;i<=99;++i)
      printf("%d ",i);
    for(int i=100;i<=9900;i+=100)
      printf("%d ",i);
    for(int i=10000;i<=990000;i+=10000)
      printf("%d ",i);

E . Takahashi and Animals (dp)

题意:有一圈小动物,喂养其中的一个相当于喂养它和下一个,每个小动物的喂养都有他的金额,问把小动物喂养完最少要多少钱。

我们很容易就能想到dp,但是如何处理第1个和第n个动物之间的关系呢?我们考虑分类讨论,对两种情况分别dp求最小值即可。
在以下的dp程序中,dp1代表喂养了第n个,dp2则反之,这两个dp只有初始话和最后答案的计算上有区别,除此之外,我们还要再设计多一维,表示是否喂养的状态。

#include<bits/stdc++.h>
#define ll long long
//const int N=1e6+5;
const int N=3e5+5;
//const int mod=1e9+7;
//const long long mod=998244353;
using namespace std;

int n,t;

ll a[N],ans;
ll dp1[N][2],dp2[N][2];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>n;
    for(int i=1;i<=n;++i)
      cin>>a[i]; 
    dp1[1][0]=dp2[1][1]=1e18;
    dp1[1][1]=a[n];
    for(int i=2;i<=n;++i)
      {
      	dp1[i][0]=dp1[i-1][1];
      	dp1[i][1]=min(dp1[i-1][0],dp1[i-1][1])+a[i-1]; 
      	dp2[i][0]=dp2[i-1][1];
      	dp2[i][1]=min(dp2[i-1][0],dp2[i-1][1])+a[i-1];      
      }
    ans=min(min(dp1[n][1],dp1[n][0]),dp2[n][1]);
    printf("%lld",ans);
}

F . Two Spanning Trees (图论)

题意:给出一个无向图,求两棵生成树,其中一棵满足除了树边外图中的其他边连接的两个顶点有祖先关系,另外一棵满足除了树边以外的的其他边连接的两个顶点没有祖先关系。

这道题看似很抽象,其实稍加画图就可以知道,这是对树边的dfs和bfs。

#include<bits/stdc++.h>
#define ll long long
//const int N=1e6+5;
const int N=2e5+5;
//const int mod=1e9+7;
//const long long mod=998244353;
using namespace std;

int n,t,m,x,y;

vector<int>e[N];
int vis[N];
queue<int>q;

void dfs(int u)
{
	vis[u]=1;
	for(auto v:e[u])
	  {
	  	if(!vis[v])
	  	  {
	  	  	printf("%d %d\n",u,v);
	  	    dfs(v);	
	  	  }
	  }
}

void bfs(int u)
{
	memset(vis,0,sizeof(vis));
	vis[u]=1;
	q.push(u);
	while(!q.empty())
      {
      	int u=q.front();
      	q.pop();
      	for(auto v:e[u])
      	  {
      	  	if(!vis[v])
      	  	  {
      	  	  	printf("%d %d\n",v,u);
      	  	  	 q.push(v);
      	  	  	 vis[v]=1;
      	  	  }
      	  }
      }
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>m;
    while(m--)
      {
      	cin>>x>>y;
      	e[x].emplace_back(y);
      	e[y].emplace_back(x);
      }
    dfs(1);
    bfs(1);
}

G . Intersection of Polygons (计算几何)

题意:给出一个多边形,以及他的各种平移后的图形,再给出多组坐标询问,问这些坐标是否交于所有图形。

我们把多边形的各个边转化为半平面作为限制条件,平移时遍历修改各个半平面,使其约束越来越小,最后在每组询问中判断是否满足半平面交即可。

#include<bits/stdc++.h>
#define ll long long
//const int N=1e6+5;
//const int N=1e5+5;
//const int mod=1e9+7;
//const long long mod=998244353;
using namespace std;

ll n,t,m;
ll x[55],y[55],u,v,flag;
ll dx[55],dy[55],c[55];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>n;
    for(int i=1;i<=n;++i)
      cin>>x[i]>>y[i];
    x[n+1]=x[1];
    y[n+1]=y[1];
    for(int i=1;i<=n;++i)
      {
      	c[i]=1e18;
      	dy[i]=x[i]-x[i+1];
      	dx[i]=y[i+1]-y[i];
      }
    cin>>m;
    for(int i=1;i<=m;++i)
      {
      	cin>>u>>v;
      	for(int j=1;j<=n;++j)
          c[j]=min(c[j],(x[j]+u)*dx[j]+(y[j]+v)*dy[j]);
      }
    cin>>t;
    while(t--)
      {
      	cin>>u>>v;
      	flag=1;
      	for(int i=1;i<=n;++i)
      	  {
      	  	if(u*dx[i]+v*dy[i]>c[i])
      	  	  {
      	  	  	flag=0;
      	  	  	break;
      	  	  }
      	  }
      	if(flag)
      	  printf("Yes\n");
      	else
      	  printf("No\n");
      }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值