每天一套题打卡|河南省第十届ACM/ICPC

A.谍报分析

题意:请你编程,快速统计出频率高的前十个单词。
每天一套题打卡|河南省第十届ACM/ICPC_第1张图片

思路:字符串输入,map哈希表map记录每个单词出现的次数,pair重载优先级

#include
using namespace std;

map mp;
string s;

typedef pair PAIR;
bool cmp(const PAIR& lhs, const PAIR& rhs) {
    if(lhs.second == rhs.second){
        return lhs.first < rhs.first;
    }
    return lhs.second > rhs.second;
}

int main(){
    char c[20010];
    while(cin>>s){
        int len = s.length();
        if(s[len-1] == '.' || s[len-1] == ','){
            for(int i=0;i vec(mp.begin(),mp.end());
    sort(vec.begin(),vec.end(),cmp);
    for(int i=0;i<10;i++){
        cout<

B.情报传递

题目:特科组的情报人员共有N人,其代号分别为0,1,……,N-1。 0号是最高领导人,特工之间有一套严格的单线联络程序,即,每个特工人员只有一个上线,他获得的情报需层层上传递到0号手里,由0号发报出去。 特工i在传递情报时,若通往到0号的通道尚未建立,则需要建立一级级单线通道;若他的上线已建立好通道,只需建立两人通道,信息发送给上线;依次类推。若特工i已建立好到0号的通道,则直接发出情报。日伪统治中心南京,既是情报来源丰富的地方,又是特工人员活动最危险的地方。因此,一旦某个特工处于不安全状态,他必须马上撤离,同时他的所有下线(处在通道上的一级级下线)也一同撤离。 已知***特科组的组织结构,你的任务是计算,当某特工i需要发送情报时,最少需要建立几个情报人员的通道;当某特工i处于不安全状态时,最少需要撤离多少人员。

思路:画图,是一颗树,边没有连,dfs向下遍历统计危险时需要撤离的数量(撤离子孙),bfs向上统计直到根结点0,edge数组记录当前边是否建立了通道,通过样例还可以看出要根0也要算一次,wa了6发最终AC

#include
using namespace std;

const int maxn = 5100;
int n,m;
int fa[maxn];
int edge[maxn][maxn];
int ans;
int vis[maxn];
int cnt;
vector v[maxn];
struct node{
    int x;
    int step;
    node(int xx,int ss){
        x = xx;
        step = ss;
    }
}; 
queue q;

void bfs(int s){
    q.push(node(s,0));
    while(!q.empty()){
        int curx = q.front().x;
        int curs = q.front().step;
        if(curx == 0){
            if(edge[0][0]){
                ans = min(ans,curs);
            }else{
                ans = min(ans,curs);
                ans++;
                edge[0][0] = 1;
            }
        }
        q.pop();
        if(curx == 0) continue;
        if(edge[fa[curx]][curx]){
            q.push(node(fa[curx],curs));
        }else{
            edge[fa[curx]][curx] = 1;
            edge[curx][fa[curx]] = 1;
            q.push(node(fa[curx],curs+1));
        }
    }
}

void dfs(int x){
    cnt++;
    for(int i=0;i>n;
    fa[0] = 0;
    for(int i=1;i<=n-1;i++){
        int d;
        cin>>d;
        fa[i] = d;
        v[d].push_back(i);
    }
    cin>>m;
    char ch[10];
    int first = 1;
    for(int i=1;i<=n;i++){
        scanf("%s",ch);
        int d;
        cin>>d;
        if(ch[0] == 'S'){
            ans = 0x3f3f3f3f;
            bfs(d);
            cout<

C.最小密钥

每天一套题打卡|河南省第十届ACM/ICPC_第2张图片

思路:因为数据量小,枚举mod的值,vis数组标记就可以了

#include
using namespace std;

int t;
int n;
int a[3005];
int vis[20005];

int main(){
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        int maxi = a[1];
        for(int i=1;i<=n;i++) if(a[i] > maxi) maxi = a[i];
        memset(vis,0,sizeof(vis));
        int ans = maxi;
        
        for(int mod = 1;mod<=maxi+1;mod++){
            bool flag = true;
            for(int i=1;i<=n;i++){
                if(!vis[a[i]%mod]){
                    vis[a[i]%mod] = 1;
                }else{
                    flag = false;
                    break;
                }
            }
            if(flag){
                ans = mod;
                break;
            }
            for(int i=0;i<=mod+1;i++) vis[i] = 0;
        }
        cout<

D.年终奖金

每天一套题打卡|河南省第十届ACM/ICPC_第3张图片

思路:DP,区间dp做多了很容易看出状态转移方程。。。然后就是边界的问题了,慢慢调。

#include
using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 110;
int n,m,c;
int a[maxn];
int dp[maxn][maxn];

int main(){
    while(cin>>n>>m>>c){
        memset(dp,inf,sizeof(dp));
        for(int i=1;i<=n;i++) cin>>a[i];
        sort(a+1,a+n+1);
        for(int i=m;i<=n;i++){
            dp[1][i] = (a[i]-a[1])*(a[i]-a[1]) + c;
        }
        //第i个人
        for(int i=2;i<=n/m;i++){
            //第i个人完成的任务数 j
            for(int j=(i-1)*m+1;j<=n;j++){
                //第i个人取到j个物品,可以由第i-1个人完成的最后一个任务k开始推出来;(所以是区间dp)
                for(int k=m;k<=j-m*(i-1);k++){
                    dp[i][j] = min(dp[i][j],dp[i-1][j-k] + (a[j]-a[j-k+1])*(a[j]-a[j-k+1]) + c );
                }
            }
        }
        int ans = inf;
        for(int i=1;i<=n/m;i++){
            ans = min(ans,dp[i][n]);
        }
        cout<

可以改成一维 O(n^2),前面这一种方法 i~人这一维可以忽略

#include
#include 
#define MAX 0x3f3f3f3f
#define min(x,y)(x

E.GDP值

还没看题

F.Binary to Prime

思路:理解题意后得知先素数打表,倒序遍历一遍给出的字符串,如果是'1',就累加起来

#include
using namespace std;

int sum = 0;
vector v;
int prime[1000010];
int storage[1000010];


void Prime(){
    for (int i = 2; i <= 1000000; i++) {
        prime[i] = true;
    }
    for (int i = 1; i * i <= 1000000; i++) {
        if (prime[i]) {
            for (int j = i * i; j <= 1000000; j += i) {
                prime[j] = false;
            }
        }
    }
}

int main(){
    Prime();
    int cur = 1;
    for(int i=1;i<=100010;i++){
        if(prime[i]){
            storage[cur++] = i;
        }
    }
    string s;
    while(cin>>s){
        sum = 0;
        for(int i=s.length()-1;i>=0;i--){
            v.push_back(s[i]);
        }
        int len = v.size();
        for(int i=0;i

G. Plumbing the depth of lake

每天一套题打卡|河南省第十届ACM/ICPC_第4张图片

题意:如果当前方块的8个方向有一个与他相等,他就是题目说的reading。统计地图上最深的(值最大)的方块

#include
using namespace std;

int t;
int a[100][100];
int vis[100][100];
int n,m;
int dr[8][2] = {{-1,0},{1,0},{0,-1},{0,1},{1,1},{1,-1},{-1,1},{-1,-1}};

bool in(int x,int y){
    return x>=1 && x<=n && y>=1 && y<=m;
}

int main(){
    cin>>t;
    while(t--){
        cin>>n>>m;
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>a[i][j];
        int ans = -0x3f3f3f3f;
        for(int x=1;x<=n;x++){
            for(int y=1;y<=n;y++){
                if(a[x][y] == 0) continue;
                for(int i = 0;i<8;i++){
                    int tx = x+dr[i][0];
                    int ty = y+dr[i][1];
                    if(in(tx,ty) && a[tx][ty] == a[x][y]){
                        ans = max(ans,a[x][y]);
                    }
                }
            }
        }
        cout<

H. Intelligent Parking Building

还没看题

你可能感兴趣的:(每天一套题打卡|河南省第十届ACM/ICPC)