第一次打CF(Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 2) )

10.30从320回寝室,睡了一会到,11.30赶快起来打。。

第一题很简单,wa了两发,很慌,。。(错在n除以二要向上取整)

第二题思路对了,判断条件好像想错了,wa数据9,半天,慌得我查了队友,他也wa9半天。。

冷静下来看了一会,发现错误。

第三题,刚开始想用,bfs  不太熟,转战dfs  还好寒假刚练习过  。轻松a过(还是在本地IDE调试半天BUG)

还剩10分钟,看了D题 感觉比C好写,没时间了  只能挂机。。。

然后写了博客,很困,但也很激动,A了三题,之前训练一般DIV2是1-2题

估计是这个寒假的蜕变吧。上学期还是太浪了,一学期学的不如一个寒假。。

等醒了后去320补题。。加油!!!!

 

好吧,上午选课,下午园设补题。。。。。

A题,水的不谈,然而我还WA了一发,第一次打  不太熟练吧。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 50000+100
int main()
{
    int n,m,z=0,f=0;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>m;
        if(m>0)
            z++;
        if(m<0)
            f++;
    }
    int q=(n+1)/2;
    if(f>=q)
    cout<<-1<<endl;
    else if(z>=q)
    cout<<1<<endl;
    else
    cout<<0<<endl;
    return 0;
}

B:当时A的时候想复杂了,还判断了A,B走下一个等级的蛋糕店,2种走法的距离和。其实不用判断,因为d1【】数组始终存的是左边,自己在纸上证明下,比较简单发现,距离始终最小,加一遍就行。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 200000+100
typedef long long ll;
ll w[maxn];
ll d1[maxn];
ll d2[maxn];
ll ab(ll n)
{
    if(n<0)
        return -n;
    return n;
}
int main()
{
    ll n,a,b;
    cin>>n;
    for(int i=1;i<=2*n;i++)
    {
        scanf("%I64d",&w[i]);
        if(d1[w[i]])
            d2[w[i]]=i;
        else
            d1[w[i]]=i;
    }
    ll ans=0;
    a=1,b=1;
    for(int i=1;i<=n;i++)
    {
        ans+=abs(d1[i]-a);
        ans+=abs(d2[i]-b);
        a=d1[i];
        b=d2[i];
    }
    /*ans+=d1[1]-1;
    ans+=d2[1]-1;
    for(int i=2;i<=n;i++)
    {
        if((ab(d2[i]-d1[i-1])+ab(d1[i]-d2[i-1]))<(ab(d2[i]-d2[i-1])+ab(d1[i]-d1[i-1])))
        {
            ans+=ab(d2[i]-d1[i-1]);
            ans+=ab(d1[i]-d2[i-1]);
        }
        else
        {
            ans+=ab(d2[i]-d2[i-1]);
            ans+=ab(d1[i]-d1[i-1]);
        }
    }*/
    printf("%I64d\n",ans);
    return 0;
}

C:直接DFS扫终点和起点的联通块,存2个数组里,然后暴力求代价最小就行。。我怕BFS写错,才写的DFS,(还好这一题就是用DFS)惭愧啊。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 200000+100
typedef long long ll;
char ma[55][55];
int v1[55][55];
int v2[55][55];
int n;
struct po
{
    int x;
    int y;
};
po p1[5000];
po p2[5000];
int c1=0,c2=0;
void dfs1(int x,int y)
{
   // printf("%d %d %c  %d\n",x,y,ma[x][y],c1);
    if((x>=1&&y>=1&&x<=n&&y<=n&&ma[x][y]=='0'&&!v1[x][y]))
    {
        p1[++c1].x=x;
        p1[c1].y=y;
        v1[x][y]=1;
        //if((x+1>=1&&y>=1&&x+1<=n&&y<=n&&ma[x][y]=='0'))
        dfs1(x+1,y);
        //if((x-1>=1&&y>=1&&x-1<=n&&y<=n&&ma[x][y]=='0'))
        dfs1(x-1,y);
       // if((x>=1&&y+1>=1&&x<=n&&y+1<=n&&ma[x][y]=='0'))
        dfs1(x,y+1);
  //      if((x>=1&&y-1>=1&&x<=n&&y-1<=n&&ma[x][y]=='0'))
        dfs1(x,y-1);
    }
    return ;
}
void dfs2(int x,int y)
{
   // printf("%d %d %c  %d\n",x,y,ma[x][y],c2);
    if((x>=1&&y>=1&&x<=n&&y<=n&&ma[x][y]=='0'&&!v2[x][y]))
    {
        v2[x][y]=1;
        p2[++c2].x=x;
        p2[c2].y=y;
        dfs2(x+1,y);
        dfs2(x-1,y);
        dfs2(x,y+1);
        dfs2(x,y-1);
    }
    return ;
}
int cal(po a,po b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int main()
{
    int x1,x2,y1,y2;
    cin>>n>>x1>>y1>>x2>>y2;
    for(int i=1;i<=n;i++)
        {

            scanf("%s",&ma[i][1]);
        }
 /*   for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        cout<<ma[i][j]<<"++"<<endl;*/
    dfs1(x1,y1);
    dfs2(x2,y2);
    //cout<<c1<<"  "<<c2<<endl;
    int x=x1,y=y1,mi=inf;
    for(int i=1;i<=c1;i++)
        for(int j=1;j<=c2;j++)
        {

            int v=cal(p1[i],p2[j]);
            mi=min(v,mi);
           // cout<<mi<<"  "<<v<<endl;
        }
    cout<<mi<<endl;
    return 0;
}

D1+D2:这一题思路很明显,怎么把思路简单的转换成代码  ,表达出来。

首先所花的时间是把所有糖果运送完。每次到一个地方尽量选离这个点远的糖果(这样在运最后一次的时候距离最小)。之前的运输时间用周期乘n,即只需求最后一次运送糖果的时间就行。然后扫一遍n,每个点的糖果运送完的距离和是:起点到这个点的距离+这个点运到只剩一个糖果的时间(n*cnt【i】)+这个点运送最后一个糖果所画的时间。每个起点n扫一遍,然后扫一遍运完各个点的糖果所化时间的最大值ans。时间复杂度O(n^2);

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MN 5000
using namespace std;
int n,m,mi[MN+5],cnt[MN+5];
int main()
{

	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
        mi[i]=50000+10;
	int u,v;
	for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        cnt[u]++;
        mi[u]=min(mi[u],(n+v-u)%n);
       // printf("%d %d %d\n",mi[u],(n+v-u)%n,i);
    }
    for(int i=1;i<=n;i++)
    {
        if(cnt[i]==0)mi[i]=0;
     //   printf("%d %d %d\n",mi[i],cnt[i],i);
    }

    for(int i=1;i<=n;i++)
    {
        //printf("\n%d %d %d\n",mi[i],cnt[i],i);
        int ans=0;
        for(int j=1;j<=n;j++)
        {
            ans=max(ans,(cnt[j]-1)*n+mi[j]+(n+j-i)%n);
        }
        printf("%d ",ans);
    }
    puts("");
	return 0;
}

E;wang anwser  吃完饭再补

这一题第一眼就看出是构造题,具体怎么构造。。

首先先让数组第一个为-1,后面全是正数,

-1,a1,a2,a3,a4…………an;全部和S

题目算法结果是,(a1+a2+。。。。。an)*(n-1);

实际是(-1+a1+a2+……an)*n;

K=S*N-(S+1)*(N-1);

S=N+K-1;

因为所以,由于每个数小于1e6,所以N至少1001,而且,还要多个N,保险起见,我们令N=1010;

那么S=1009+K;

然后,-1后面的数组直接分配到0就行了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#define M 1000000
using namespace std;
int main()
{
	int k;
	cin>>k;
	cout<<1010<<endl;
	int ans=k+1010;
	printf("%d ",-1);
	for(int i=2;i<=1010;i++)
    {
        if(ans>M)
        {
            ans-=M;
            printf("%d ",M);
        }
        else
        {
            if(ans>=1)
            {
                printf("%d ",ans);
                ans=0;
            }
            else
                printf("%d ",0);
        }
    }
    puts("");
	return 0;
}

 

 

人一我百,人百我万.夕林山寸,寻梦指尖!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值