2020hdu多校第四场比赛及补题

1005 Equal Sentences

队友过的一题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 1e5 + 7;
const int MOD = 1e9 + 7;
 
int T;
int n;
string str;
string tmp, word;
int cnt;
int dp[MAXN][2];
int vis[MAXN];
int ans;
 
int32_t main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> T;
    while (T--)
    {
        memset(vis, 0, sizeof(vis));
        cnt = 0;
        ans = 0;
        word = "";
        cin >> n;
        for (int i = 1; i <= n; ++i)
        {
            cin >> str;
            if (str != word)
            {
                cnt++;
                word = str;
            }
            vis[i] = cnt;
        }
        dp[0][0] = dp[0][1] = 0;
        dp[1][0] = 1;
        dp[1][1] = 0;
        for (int i = 2; i <= n; ++i)
        {
            if (vis[i] != vis[i - 1])
            {
                dp[i][0] = dp[i - 1][0] + dp[i - 1][1] % MOD;
                dp[i][1] = dp[i - 1][0] % MOD;
            }
            else
            {
                dp[i][0] = dp[i - 1][0] + dp[i - 1][1] % MOD;
                dp[i][1] = 0 % MOD;
            }
        }
        ans = dp[n][0] + dp[n][1];
        ans %= MOD;
        cout << ans << endl;
    }
    return 0;
}

  

1002 Blow up the Enemy

队友过的一题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int data[1002];
int main(void){
    int t;
    cin >> t;
    int n;
    while(t--){
        scanf("%d", &n);
        int ai,di;
        int minn=999999999;
        for(int i=1;i<=n;i++){
            scanf("%d %d", &ai, &di);
            if((100%ai)==0){
                data[i]= di*(100/ai-1);
            }else{
                data[i] = di*(100/ai);
            }
            if(minn > data[i]){
                minn = data[i];
            }
        }
        int ans = 0;
        for(int i=1;i<=n;i++){
            if(minn < data[i]){
                ans += 10;
            }else if(minn == data[i]){
                ans += 5;
            }else{
                ans += 0;
            }
        }
        double res = (double)ans/(double)n/10.0;
        cout << res << endl;
    }
    return 0;
}

  

1011 Kindergarten Physics

???题,我们队三人还真一直在算,直到我偷听到答案。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const double res = 1e-10;
int main()
{
    int T,a,b,d;
    double t;
    cin>>T;
    while(T--){
        cin>>a>>b>>t>>d;
        t-=res;
        printf("%.10lf\n",t);
    }
    return 0;
}

 

1004 Deliver the Cake

n个点,m条边求最短路,

点有3个状态,L,R,M

L点到R点或R点到L点要额外增加 x 的距离,M点可当成L点或当成R点,M点不能同时当成L点和R点

看起来挺简单的,但比赛时没做出来,一直T

我乱魔改dijkstra,用了自己不会的语法

还是拆点好,直接把M点拆成一个L点和一个R点,然后建图,拆点建图细节比较多,我改了挺久

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<vector>
 
using namespace std;
const int MAXN = 2e5+7;
const long long INF = 1e18+7;
 
template<class T>inline void read(T& res)
{
    char c; T flag = 1;
    while ((c = getchar()) < '0' || c > '9')if (c == '-')flag = -1; res = c - '0';
    while ((c = getchar()) >= '0' && c <= '9')res = res * 10 + c - '0'; res *= flag;
}
 
struct EDGE{
    int to,next;
    long long d;
}edge[MAXN*8];
int head[MAXN],tot;
 
long long n,m,s,t,x;
char shou[MAXN];
long long dis[MAXN];
 
void add(int u,int v,long long w){
    ++tot;
    edge[tot].to = v;
    edge[tot].d = w;
    edge[tot].next = head[u];
    head[u] = tot;
}
 
void dijkstra(int st) {
    priority_queue< pair<long long,int> , vector<pair<long long,int> >, greater<pair<long long,int> > >que;
    dis[st] = 0;
    que.push({0,st});
    while(!que.empty()){
        int node = que.top().second;
        long long dt = que.top().first;
        if(dis[node] < dt){
            que.pop();
            continue;
        }
        que.pop();
        for(int i = head[node];i;i = edge[i].next ){
            int po = edge[i].to;
            long long lo = edge[i].d;
            if(dis[po] > dis[node] + lo){
                dis[po] = dis[node] + lo;
                que.push({dis[po],po});
            }
        }
    }
    return;
}
 
int main()
{
    //freopen("D.in","r",stdin);
    int T;
    int u,v;
    long long d;
    cin>>T;
    while(T--){
        tot = 0;
        scanf("%lld%lld%lld%lld%lld",&n,&m,&s,&t,&x);
        scanf("%s",shou + 1);
        for(int i = 1;i <= n; i++){
            head[i] = head[i+n] = 0;
            dis[i] = dis[i+n] = INF;
        }
        for(int i = 1;i <= m; i++ ){
            read(u);read(v);read(d);
            if(shou[u] == 'R') u += n;
            if(shou[v] == 'R' ) v += n;
            if(u <= n && v <= n) {
                add(u,v,d);
                add(v,u,d);
            }
            else if(u>n&&v>n){
                add(u,v,d);
                add(v,u,d);
            }
            else {
                add(u,v,d+x);
                add(v,u,d+x);
            }
            if(u<=n&&v<=n&&shou[u]=='M'&&shou[v]=='M'){
                add(u,v+n,d+x);
                add(v+n,u,d+x);
                add(u+n,v,d+x);
                add(v,u+n,d+x);
                add(u+n,v+n,d);
                add(v+n,u+n,d);
            }
            else if (u<=n&&shou[u] == 'M'){
                if(v<=n){
                    add(u+n,v,d+x);
                    add(v,u+n,d+x);
                }
                else{
                    add(u+n,v,d);
                    add(v,u+n,d);
                }
            }
            else if(v<=n&&shou[v] == 'M'){
                if(u<=n){
                    add(u,v+n,d+x);
                    add(v+n,u,d+x);
                }
                else{
                    add(u,v+n,d);
                    add(v+n,u,d);
                }
            }
        }
        long long ans;
        if(shou[s]=='L'){
            dijkstra(s);
            ans = min(dis[t],dis[t+n]);
        }
        else if(shou[s]=='R'){
            dijkstra(s+n);
            ans = min(dis[t],dis[t+n]);
        }
        else{
            dijkstra(s);
            ans = min(dis[t],dis[t+n]);
            for(int i = 1;i<=n;i++){
                dis[i] = dis[i+n] = INF;
            }
            dijkstra(s+n);
            ans = min(ans,min(dis[t],dis[t+n]));
        }
        printf("%lld\n",ans);
    }  
    return 0;
}

  

1007 Go Running

 

 

补题

看了下队友的代码,队友的代码比较神奇,有我没见过的语法,变量名又是fuck,又是shit的。。。

其实是挺简单的一题,我一看,就想到这是一个二分图题,可惜我比赛时没看这题(一直在搞1004qAq)

题目意思可以转化为给n组 t 和 x,每组t,x表示 t-x或t+x的位置上有人,问最少有多少人

把每个t-x点放到左边,每个t+x点放到右边,每组的t-x点连向对应的t+x点,发现就是个二分图最小点覆盖问题,最小点覆盖就是二分图最大匹配(我当时忘记了二分图最小点覆盖是什么,但直觉上感觉这就是个二分图最大匹配)

 

虽然一下就想到二分图,但我还是补了挺久

我想用网络流来做二分图最大匹配,而这题数据比较大,要用dinic,而我只会EK,不会dinic,我dinic用的是软白的板子,用不来,在那套板子套了挺久还是没套好,然后又去检查建图,最后只好用我好久没用的二分图最大匹配模板,重新写一遍,过了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
#include<queue>
using namespace std;
const int MAXN = 1e5+7;
vector<int> graph[MAXN];
int n;
int pei[MAXN],cc[MAXN];
bool eft(int st, int cur){
    if(cc[st]==cur) return false;
    cc[st] = cur;
    for(int i = 0;i<graph[st].size();i++){
        int po = graph[st][i];
        if(pei[po] == st) continue;
        if(pei[po] == -1||eft(pei[po],cur)){
            pei[po] = st;
            return true;
        }
    }
    return false;
}
int main()
{
    //freopen("G.in","r",stdin);
    int T;
    cin>>T;
    int t,x;
    while(T--){
        cin >> n;
        map<long long,int>ant1,ant2;
        int cnt1 = 0,cnt2 = 0;
        for(int i = 1;i <= n;i++){
            scanf("%d%d",&t,&x);
            if(!ant1[x-t]) ant1[x-t] = ++cnt1;         
            if(!ant2[x+t]) ant2[x+t] = ++cnt2;
            graph[ant1[x-t]].push_back(ant2[x+t]);
        }  
        for(int i = 1;i <= cnt2;i++) pei[i] = -1;
        for(int i = 1;i <= cnt1;i++) cc[i] = -1;
        int ans = 0;   
        for(int i = 1;i <= cnt1;i++) if(eft(i,i)) ans++;
        cout<<ans<<endl;
        for(int i = 1;i <= cnt1;i++) graph[i].clear();
    }
    return 0;
}

  

 

posted @   beta_dust  阅读(133)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示