The 18th Zhejiang Provincial Collegiate Programming Contest题解

A. League of Legends

水题。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[6]; 
int b[6]; 

signed main()
{   
    for(int i = 1; i <= 5; i++) cin >> a[i];
    for(int i = 1; i <= 5; i++) cin >> b[i]; 
    int num1 = 0, num2 = 0;
    for(int i = 1; i <= 5; i++){
        num1  += a[i];
        num2 += b[i]; 
    }
    if(num1 >= num2){
        printf("Blue\n"); 
    }
    else printf("Red\n"); 
    return 0;
}

L、String Freshman

首字母出现两次即为不合格。因为这样会造成忽略。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

int n;
char s[100010];
int main()
{  
    scanf("%d%s", &n, s + 1);
    for(int i = 2; i <= n; i++) if(s[i] == s[1]) return puts("Wrong Answer"), 0;
    puts("Correct");
    return 0;
}

G、Wall Game

用map维护坐标编号,用并查集维护连通块,合并的时候维护连通块内的坐标数量和应删除边即可。

点击查看代码
#pragma GCC optimize (2)
#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long

template <class T>
inline void read(T& a){
    T x = 0, s = 1;
    char c = getchar();
    while(!isdigit(c)){
        if(c == '-') s = -1;
        c = getchar(); 
    }
    while(isdigit(c)){
        x = x * 10 + (c ^ '0');
        c = getchar(); 
    }
    a = x * s;
    return ; 
}

map <pair<int, int>, int> G; 

int fa[N];

int find_fa(int x){
    return x == fa[x] ? x : fa[x] = find_fa(fa[x]); 
}

int n; 
int tot = 0; 
int del[N];   // del: 每个联通块应当删去的边的个数 
int num[N]; 

int fx[7] = {0, 1, 1, -1, -1, 0, 0}; 
int fy[7] = {0, 0, -1, 0, 1, 1, -1};                       

inline void merge(int u, int v, int delta){
    int fau = find_fa(fa[u]), fav = find_fa(fa[v]); 
    if(fau != fav){
        num[fav] += num[fau]; 
        del[fav] += del[fau] + delta; 
        fa[fau] = fav; 
    }
    return ; 
}

void seek(int x, int y){
    int dx, dy;
    del[G[make_pair(x, y)]] = 0; 
    num[G[make_pair(x, y)]] = 1;  // 1个点 

    set <int> s; 
    map <int, int> g; 

    for(int i = 1; i <= 6; i++){
        dx = x + fx[i]; 
        dy = y + fy[i]; 
        if(!G.count(make_pair(dx, dy))) continue;   // dx,dy 没有被占领
        s.insert(find_fa(G[make_pair(dx, dy)])); 
        g[find_fa(G[make_pair(dx, dy)])]++; 
    }
    
    for(auto it : s){
        
        merge(find_fa(G[make_pair(x, y)]), it, g[it]); 
    }

    return ; 
}

int main(){
    read(n);
    for(int i = 1; i <= (int)1e6; i++)
        fa[i] = i; 

    for(int i = 1; i <= n; i++){
        int opt, x, y;
        read(opt), read(x), read(y); 
        if(!G.count(make_pair(x, y))) G[make_pair(x, y)] = ++tot; 
        if(opt == 1){
              // 向六个边去找
            seek(x, y); 
        }
        else {
             
            int f = find_fa(G[make_pair(x, y)]);  
            // printf("x: %d  y: %d  id: %d  num: %d  del: %d\n", x, y, find_fa(G[make_pair(x, y)]), num[f], del[f]); 
            printf("%d\n", num[f] * 6 - del[f] * 2); 
        }
    }
    return 0; 
}

J、Grammy and Jewelry | header |

最短路加完全背包

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long

template <class T>
inline void read(T& a){
	T x = 0, s = 1;
	char c = getchar();
	while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
	while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
	a = x * s;
	return ;
}

int n, m, T;
struct node{
  int u, v, w, next;
  /* data */
} t[N << 1];
int head[N];

int bian = 0;
inline void addedge(int u, int v, int w){
  t[++bian] = (node){u, v, w, head[u]}, head[u] = bian;
  return ; 
}

int a[N]; 

ll dis[N]; 
bool vis[N]; 

struct point{
  int id;
  ll dis; 

  bool operator < (const point &a) const{
    return dis > a.dis; 
  }
} ; 

void dij(int s){
  memset(vis, 0, sizeof(vis));
  memset(dis, 0x3f3f3f3f3f3f3f, sizeof(dis)); 
  priority_queue <point> q; 
  q.push((point){s, 0}); 
  dis[s] = 0;
  while(!q.empty()){
    int u = q.top().id; q.pop();
    if(!vis[u]){
      vis[u] = 1;
      for(int i = head[u]; i; i = t[i].next){
        int v = t[i].v;
        if(dis[v] > dis[u] + t[i].w){
          dis[v] = dis[u] + t[i].w;
          if(!vis[v]) q.push((point){v, dis[v]}); 
        }
      }
    }
  }
  return ; 
}

ll dp[N]; // i 时间内的最多价值

int main(){
  // freopen("hh.txt", "r", stdin); 
  read(n), read(m); read(T); 
  for(int i = 2; i <= n; i++) read(a[i]);
  for(int i = 1; i <= m; i++){
    int x, y;
    read(x), read(y);
    addedge(x, y, 1); 
    addedge(y, x, 1);
  }
  dij(1); 

  for(int i = 2; i <= n; i++){
    for(int j = dis[i] * 2; j <= T; j++){
      if(j - (dis[i] << 1) >= 0){    // 完全背包,可以选择无数次(不断从前面的累加)
        dp[j] = max(dp[j], dp[j - (dis[i] << 1)] + a[i]);    
      }
    }
  }

  for(int i = 1; i <= T; i++)
    printf("%lld ", dp[i]); 

  return 0;
}

posted @ 2022-10-23 23:53  雪之下,树之旁  阅读(60)  评论(0编辑  收藏  举报