Codeforces Round #542(div2)

题目链接:http://codeforces.com/contest/1130

A. Be Positive

题意:

给定n个数,a[1]~a[n],求一个数m,使得a[i]/m(向上取整)是正数的个数大于等于n/2(向上取整)

解析:

正数/1>0,负数/-1>0,0无法得正数

我们分别记录正数和负数的个数a,b,如果a>=(n+1)/2 =>1,如果b>=(n+1)/2=>-1

ac:

#include<bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);
#define pb push_back
#define ll long long
#define mod 1000000007
#define per(i,a,b) for(int i=a;i<b;i++)
#define rep(i,a,b) for(int i=a;i>=b;i--)
#define MAXN 305
using namespace std;

int a[MAXN];


int main()
{
    IOS
    //freopen("in.txt","r",stdin);
    int n,a=0,b=0,x;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        if(x>0)
            a++;
        else if(x<0)
            b++;
    }
    if(a>=(n+1)/2)
        printf("1\n");
    else if(b>=(n+1)/2)
        printf("-1\n");
    else
        printf("0\n");
    return 0;
}

B. Two Cakes

题意:两个人买蛋糕,蛋糕一层比一层小,规定先买小,再买大,即先买1,再买2,...最后买n

有2n家店,每家店都是只出售一个等级蛋糕的一个,相邻蛋糕店的距离为1,

两人刚开始都在最左边,问两个人最少走多长距离可以买好两个蛋糕

解析:

只要比较第一次出现的1~n层,和第二次的1~n层,分别计算求和,用vector方便计算

注意sum可能大于int,要用ll

ac:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define rep(i,x,n) for(ll i=x;i<n;i++)
#define pb push_back
#define f first
#define s second

int n,last1,last2;
vector<int> v[100100];
int main()
{
	cin >> n;
	for(int i=0;i<2*n;i++)
    {
		int x;
		cin >> x;
		v[x].push_back(i);
	}

	long long ans = 0;
	for(int i=1;i<=n;i++)
	{
		ans += abs(v[i][0]-last1)+abs(v[i][1]-last2);
		last1 = v[i][0];
		last2 = v[i][1];
	}
	cout << ans << endl;
	return 0;
}

C. Connect

题意:给两个位置A(a,b),B(c,d),需要从A到B,图中有一些水路,不能走水,但可以建隧道

隧道成本为:(rs−rt)^2+(cs−ct)^2   (rs,cs),(rt,ct)分别为隧道两端,问最小的从建隧道的最小成本

解析:

数据量很小,我们考研暴力做

用深搜或者广搜寻找变通块,遍历A连通块和B连通块的建桥成本,找最小的成本

ac:

#include<bits/stdc++.h>
#define MAXN 51
using namespace std;
int tx[4]={0,1,0,-1};
int ty[4]={1,0,-1,0};

char mp[MAXN][MAXN];
int vis[MAXN][MAXN];
int n;
struct node
{
    int x,y;
}aa[MAXN*MAXN],bb[MAXN*MAXN];

int cnta=1,cntb=1;

void dfs(int a,int b)
{
    for(int i=0;i<4;i++)
    {
        int dx=a+tx[i];
        int dy=b+ty[i];
        if(dx>=0&&dy>=0&&dx<n&&dy<n)
        {
            if(mp[dx][dy]=='0'&&vis[dx][dy]==0)
            {
                aa[cnta].x=dx;
                aa[cnta].y=dy;
                cnta++;
                vis[dx][dy]=1;
                dfs(dx,dy);
            }
        }
    }
}

void dfs2(int a,int b)
{
    for(int i=0;i<4;i++)
    {
        int dx=a+tx[i];
        int dy=b+ty[i];
        if(dx>=0&&dy>=0&&dx<n&&dy<n)
        {
            if(mp[dx][dy]=='0'&&vis[dx][dy]==0)
            {
                bb[cntb].x=dx;
                bb[cntb].y=dy;
                cntb++;
                vis[dx][dy]=1;
                dfs2(dx,dy);
            }
        }
    }
}

int main()
{
    int a,b,c,d;
    scanf("%d",&n);
    scanf("%d%d",&a,&b);
    scanf("%d%d",&c,&d);
    for(int i=0;i<n;i++)
        scanf("%s",&mp[i]);
    aa[0].x=a-1,aa[0].y=b-1;
    bb[0].x=c-1,bb[0].y=d-1;

    memset(vis,0,sizeof(vis));
    dfs(a-1,b-1);
    memset(vis,0,sizeof(vis));
    dfs2(c-1,d-1);

    int maxs=99999999;
    for(int i=0;i<cnta;i++)
        for(int j=0;j<cntb;j++)
        {
            maxs=min(maxs,(aa[i].x-bb[j].x)*(aa[i].x-bb[j].x)+(aa[i].y-bb[j].y)*(aa[i].y-bb[j].y));
        }
    printf("%d\n",maxs);
}

D Toy Train 

题意:

有一条环形火车线路,有n个站,火车只能从a站到a+1站,或者从n到1(环形)

有m个需求,需要从a运送一个糖果到b

每次经过一个火车站只能装一个糖果

问最少走多少路可以装运完所有糖果(起点1~n,输出n个结果)

解析:

一个时间在同一火车站,只能装1个糖果,呢么在a站有k个糖果需要装,我们必须让火车循环k-1次

最后一次只要到终点就完成,最后一次是从a出发的运送路线最短的dis(i,e)

我们找到最多起始的站,呢么别的运算路线都可以在k-1中分别完成,呢么结果就是maxcnt(i)*n+dis(s,i)+dis(i,e)

如果有多个起始站的站,呢么选择最大的dis(s,i)+dis(i,e),这样才能把所有的需要全部包含进去

ac:

#include<bits/stdc++.h>
#define ll long long
#define MAXN 100005
using namespace std;

int cnt[MAXN]={0};
int mind[MAXN]={0};

int dis(int a,int b,int n)
{
    if(a>b)
        return n-a+b;
    else
        return b-a;
}

int main()
{
    int n,m,a,b;
    scanf("%d%d",&n,&m);
    int maxa,maxb;
    for(int i=0;i<=n;i++)
        mind[i]=9999999;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&a,&b);
        cnt[a]++;
        mind[a]=min(mind[a],dis(a,b,n));
    }

    for(int i=1;i<=n;i++)
    {
        ll ans=0;
        for(int j=1;j<=n;j++)
        {
            if(cnt[j]==0) continue;
            ans=max(ans,(ll)(cnt[j]-1)*n+mind[j]+dis(i,j,n));
        }
        printf("%I64d ",ans);
    }
    return 0;
}

E. Wrong Answer

解析:

构造题

官方题解:

第一个数放-1,后面长为len,和为sum,每个都不为负数

k=(sum−1)(len+1)−sum⋅len=sum−len−1

随便代入一个len,构造输出,因为|ai|≤10^6,len>1000

ac:

#include<bits/stdc++.h>
#define ll long long
#define MAXN 2005*2
using namespace std;

void print(int k,int n)
{
    printf("-1 ");
    for(int i=0;i<k;i++)
    {
        if(n>=1000000)
        {
            printf("1000000 ");
            n=n-1000000;
        }
        else
        {
            printf("%d ",n);
            n=0;
        }
    }
}

int main()
{
    ll n;
    cin>>n;
    printf("2000\n");
    int k=1999;
    n=k+1+n;
    print(k,n);
}

猜你喜欢

转载自blog.csdn.net/weixin_41183791/article/details/88431956
今日推荐