Codeforces Round #581 div.2 A,B,C

A

  • 题意: 给出一个二进制数,求比这个数小的四的整次方倍数的个数
  • 思路: 直接求长度除2,若长度为奇数且除最高次位外其他位数有1,则答案加1.
    二进制数的每两位代表一个四进制数

B

  • 题意: 一个序列,其中的每个数要么是该序列中一个数的两倍,要么是1,给出不同数字的最大,最小个数\(l,r\),求这个序列和的最大值和最小值
  • 思路: 最小和肯定前面全是1后面l-1个依次递增2倍,最大和肯定前面r个递增到最大,后面n-r个全是最大的数

C

  • 题意: 给出一个无权有向图,在给出一个路径,让你进行压缩,使得压缩后的路径长度与压缩前的路径长度相等.
  • 思路: 能够被压缩,则一定是最短路,将非最短路的路径记录下来即可,而非最短路肯定能找到一个中转点(终点前一个点),使得起点到中转点(若不是最短路,则该点不会被压缩),中转点到终点都是最短路. 求最短路,当前起始点为q,向后找到第一个距离大于最短路距离的点p,将p前面的点加入到路径中.
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int M = 1e6+10;
const int N = 120;
int n,m;
int p[M];
int G[N][N];
char buf[N];
 
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%s",buf+1);
        for(int j=1;j<=n;++j){
            if(buf[j]=='1') G[i][j] = 1;
            else  G[i][j] = INF;
        }
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i)   scanf("%d",&p[i]);
    for(int k=1;k<=n;++k){
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j){
                G[i][j] = min(G[i][j],G[i][k]+G[k][j]);
            }
        }
    }
    int st = p[1],po = 1;
    vector<int> ans;
    ans.push_back(st);
    for(int i=2;i<=m;++i){
        if(i-po != G[st][p[i]] || p[i]==st){
            ans.push_back(p[i-1]);
            st = p[i-1];
            po = i-1;
        }
    }
    ans.push_back(p[m]);
    printf("%d\n",ans.size());
    for(auto i:ans){
        printf("%d ",i);
    }
    return 0;
}

题目要求两个相同点不能同时出现,要特判

猜你喜欢

转载自www.cnblogs.com/xxrlz/p/11387247.html