Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 2)

Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 2)

题目链接:Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 2)

 

A题题解

  • 题意
  • 题意是给你一串整数,,要找到一个除数使得每一个数被除后正数的个数大于等于 n2⌈n2⌉,,,
  • 分析
  • 统计出所有正数,负数的个数,,正数多那个除数就是1,负数多就是-1
  • AC代码
/*
author:Agnel_Cynthia
theme:思维
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//fgets getline
# define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
//set<int> s;
ll mod = 1e9 + 7;
int main(){
    IOS;
int n;
cin >> n;
ll sum ;
if(n % 2== 0)
 sum = n / 2;
else 
sum = n / 2 + 1;
int a= 0 , b = 0;
for(int i =0 ; i < n ; i ++){
    int x ;
    cin >> x;
    if(x > 0) a ++;
    else if(x < 0) b++;
}
if(a >= sum) cout << 1 << endl;
else if(b >= sum) cout << -1 << endl;
else cout << 0 << endl;
return 0;
}
View Code

 

B题题解

  • 题意
  • 两个人买蛋糕,蛋糕一层比一层小,规定先买小,再买大,即先买1,再买2,...最后买n
  • 有2n家店,每家店都是只出售一个等级蛋糕的一个,相邻蛋糕店的距离为1,
  • 两人刚开始都在最左边,问两个人最少走多长距离可以买好两个蛋糕
  • 解析
  • 只要比较第一次出现的1~n层,和第二次的1~n层,分别计算求和,用vector方便计算
  • 注意sum可能大于int,要用ll
  • AC代码
/*
author:Agnel_Cynthia
theme:模拟
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//fgets getline
# define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
//set<int> s;
ll mod = 1e9 + 7;
int a[200000],b[200000];
int main(){
    IOS;
    int n;
    cin >> n;
    for(int i = 1; i <=  2 *n; i ++){
        int x;
        cin >> x ;
        if(a[x]==0)
        a[x]  = i ;
        else 
        b[x] = i;
    //    cout << b[x] << endl;
    }
//        for(int i = n + 1; i <= 2 *  n; i ++){
//        int x;
//        cin >> x ;
//        b[x]  = i ;
//    }
    ll sum = 0;
    a[0] = 1, b[0] = 1;
    for(int i = 0; i < n ; i++){
    //    cout << a[i] <<endl;
            sum += abs(a[i+1] - a[i]);
    }
    //cout <<sum ;
    for(int i = 0; i < n ; i++){
        sum += abs(b[i+1] - b[i]);
    }
    cout << sum << endl;
return 0;
}
View Code

 

C题题解

  • 题意:
  • 给两个位置A(a,b),B(c,d),需要从A到B,图中有一些水路,不能走水,但可以建隧道
  • 隧道成本为:(rs−rt)^2+(cs−ct)^2   (rs,cs),(rt,ct)分别为隧道两端,问最小的从建隧道的最小成本
  • 解析:
  • 数据量很小,我们考研暴力做
  • 用深搜或者广搜寻找变通块,遍历A连通块和B连通块的建桥成本,找最小的成本
  • AC代码
/*
author:Agnel_Cynthia
theme:暴力,搜索
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//fgets getline
# define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
//set<int> s;
ll mod = 1e9 + 7;
int n ;
//int a[400000];
char mp[55][55];
int vis[55][55];
struct note
{
    int x,y;
}mp1[55 * 55],mp2[55 * 55];


int tx[4] = {0,1,0,-1};
int ty[4] = {1,0,-1,0};

int cnta = 1,cntb = 1;
void dfs1(int x , int y){
    for (int i = 0; i < 4; ++i)
    {
        int dx = x + tx[i];
        int dy = y + ty[i];
        /* code */
        if(dx >= 0 && dx <= n-1 && dy >= 0 && dy < n){
            if(mp[dx][dy]=='0' && !vis[dx][dy])
            {
                mp1[cnta].x = dx;
                mp1[cnta].y = dy;
                cnta++;
                vis[dx][dy] = 1;
                dfs1(dx,dy); 
            }
        }
    }
}

void dfs2(int x ,int y){
    for(int i = 0; i < 4 ; i++){
        int fx = x + tx[i];
        int fy = y + ty[i];

        if(fx >= 0 && fx < n && fy >= 0 && fy < n){
            if(mp[fx][fy] == '0' && !vis[fx][fy]){
                    mp2[cntb].x = fx;
                    mp2[cntb].y = fy;
                    cntb++;
                    vis[fx][fy] = 1;
                    dfs2(fx,fy);

            }
        }
    }
}



int main(){
    IOS;
    //int n;
cin >> n;
int a , b ,c ,d;
cin >> a >> b >> c >> d;
for(int i = 0 ; i < n ; i++){
    cin >> mp[i];
}
mp1[0].x = a - 1,mp1[0].y = b - 1;
mp2[0].x = c - 1,mp2[0].y = d - 1;
dfs1(a-1,b-1);
memset(vis,0,sizeof(vis));
dfs2(c-1,d-1);

int maxn = 999999999;
for(int i = 0; i < cnta; i++)
for(int j = 0; j < cntb; j ++){
    maxn = min(maxn,(mp1[i].x - mp2[j].x) * (mp1[i].x - mp2[j].x) + (mp1[i].y - mp2[j].y) * (mp1[i].y - mp2[j].y));
}
cout << maxn << endl;
return 0;
}
View Code

 

D题题解

  • 题意:
  • 有一条环形火车线路,有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代码
/*
author:Agnel_Cynthia
theme:模拟
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//fgets getline
# define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
//set<int> s;
ll mod = 1e9 + 7;
int cnt[100005],mind[100005];

int dis(int a,int b,int n){
    if(a > b)
    return n - a + b;
    else 
    return b - a;
}
int main(){
    IOS;
    int n,m,a,b;
    cin >> n >> m;
    int maxa,maxb;
    for(int i = 0; i <= n ; i++){
        mind[i] = 9999999;
    }
    for(int i = 0; i < m; i ++){
        cin>> 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));
        }
        cout << ans << " ";
    }
 }
View Code

 

E题题解

  • 解析:
  • 构造题
  • 官方题解:
  • 第一个数放-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);
}
官方题解

 

  • 题意
  • 一个数列求出最大的 区间和乘以区间长度,
  • 他给的算法当前面一段区间和出现负数就舍弃了,没有考虑长度对最后答案的影响,
  • 题目要我们构造一个数列,,使得这个数列的正确答案比它的做法算出的结果大k
  • 分析
  • 可以构造一个前面1998个都是0,后面一个数是-p,一个时p + q,
  • 这样正确的答案就是 2000q2000q,他算出的答案就是 p+qp+q,
  • 要大k,就是 2000q(p+q)=k2000q−(p+q)=k,也就是 q=p+k1999q=p+k1999 ,为了保证p,q都是整数,那么就设 p=1999k%1999p=1999−k%1999,这样算出的q就是整数,
  • AC代码
/*
author:Agnel_Cynthia
theme:思维,构造
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//fgets getline
# define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
//set<int> s;
ll mod = 1e9 + 7;

int main(){
    IOS;
    int k;
    cin >> k;
    cout << 2000 << endl;
    for(int i = 1;  i <= 1998; i++)
    cout << 0 << " ";
    //这样就可以保证p为 整数 ,减去多余的余数 
    int q = 1999 - k % 1999;
    int p = (q+k) / 1999;
    //cout << q << " " << p ;
    cout << -q << " " << p + q << endl;
    return 0;
}
View Code

 

posted @ 2019-03-29 01:05  Agnel_Cynthia  阅读(166)  评论(0编辑  收藏  举报
Live2D