indeed 4.22 第一次网测

1.第一题 没有看

2. 由于数据范围很小,所以每一层需要全排列,寻找最小的花费,然后所有层加起来就是最后的结果。

 1 #include<bits/stdc++.h>
 2 #define pb push_back
 3 typedef long long ll;
 4 using namespace std;
 5 typedef pair<int, int> pii;
 6 const int maxn = 1e3 + 10;
 7 int n;
 8 int m;
 9 int a[110][10][2];
10 int p[10];
11 
12 void solve() {
13     cin >> n >> m;
14     ll res = 0;
15     for (int j = 0; j < n; j++) {
16             cin >> a[0][j][0] >> a[0][j][1];
17         }
18     for (int i = 1; i <= m; i++) {
19         for (int j = 0; j < n; j++) {
20             cin >> a[i][j][0] >> a[i][j][1];
21         }
22         if(i == 0) continue;
23         for (int j = 0; j < n; j++)
24             p[j] = j;
25         ll mr = INT_MAX;
26         do {
27             ll t = 0;
28             for (int j = 0; j < n; j++) {
29                 t += abs(a[i][p[j] ][0] - a[i - 1][j][0] ) + abs(a[i][p[j] ][1] - a[i - 1][j][1] );
30             }
31             mr = min(t, mr);
32         } while(next_permutation(p, p + n));
33         res += mr;
34     }
35     cout << res << endl;
36 
37 }
38 
39 int main() {
40     freopen("test.in", "r", stdin);
41     //freopen("test.out", "w", stdout);
42     ios::sync_with_stdio(0);
43     cin.tie(0); cout.tie(0);
44     solve();
45     return 0;
46 }
View Code

3.数据范围也是很小,枚举每一条边,然后存在不存在,进行判断累加。边的个数6 * 5  / 2 = 15. 1 << 15 = 32000. 然后乘上判断连通的复杂度,结果也是很小。

判断连通可以用bfs或者dfs, dsu都是可以的。

 1 #include<bits/stdc++.h>
 2 #define pb push_back
 3 typedef long long ll;
 4 using namespace std;
 5 typedef pair<int, int> pii;
 6 const int maxn = 1e3 + 10;
 7 int n, m;
 8 //set<pii> se;
 9 int f[10];
10 int a[10][10];
11 int b[10][10];
12 void init() {
13     for (int i = 0; i <= n; i++) f[i] = i;
14 }
15 int fd(int x) {
16     if(x == f[x]) return x;
17     return f[x] = fd(f[x]);
18 }
19 bool check() {
20     int sz = n;
21     for (int i = 1; i <= n; i++) {
22         for (int j = i + 1; j <= n; j++) {
23             if(a[i][j]) {
24                 int t1 = fd(i);
25                 int t2 = fd(j);
26                 if(t1 != t2) {
27                     sz--;
28                     f[t1] = t2;
29                 }
30             }
31         }
32     }
33     return sz == 1;
34 }
35 ll res;
36 
37 void work(int x, int y) {
38     //cout << x << " " << y << endl;
39     if(x > n) {
40         init();
41         res += check();
42         return;
43     }
44     if(y > n) {
45         work(x + 1, x + 2);
46         return;
47     }
48     work(x, y + 1);
49     if(b[x][y]) return;
50     a[x][y] = a[y][x] = 1;
51     work(x, y + 1);
52     a[x][y] = a[y][x] = 0;
53 }
54 void solve() {
55     cin >> n >> m;
56     int x, y;
57     for (int i = 0; i < m; i++) {
58         cin >> x >> y;
59         //if(x > y) swap(x, y);
60         //se.insert({x, y});
61         b[x][y] = b[y][x] = 1;
62     }
63     work(1, 2);
64     cout << res << endl;
65 }
66 
67 int main() {
68     freopen("test.in", "r", stdin);
69     //freopen("test.out", "w", stdout);
70     ios::sync_with_stdio(0);
71     cin.tie(0); cout.tie(0);
72     solve();
73     return 0;
74 }
View Code

4. 第四题稍微花了一些时间。 首先题目求解满足条件的最小, 那就是比这个大的都是可以满足条件的, 满足二分的性质。

然后给定答案,如何快速的判断是否满足要求, 贪心策略进行。由于 n = 1e4, 这个数其实挺小的, 排序, 贪心 可以的。

 1 #include<bits/stdc++.h>
 2 #define pb push_back
 3 typedef long long ll;
 4 using namespace std;
 5 typedef pair<int, int> pii;
 6 const int maxn = 1e4 + 10;
 7 int n, a, b;
 8 ll h[maxn];
 9 ll tmp[maxn];
10 int tot;
11 bool check(ll x) {
12     ll ra, rb;
13     ra = rb = 0;
14     tot = 0;
15     for (int i = 0; i < n; i++) {
16         if(h[i] >= x) {
17             ll c = h[i] / x;
18             if(ra + c > a) {
19                 ll t = h[i] - x * (a - ra);
20                 ra = a;
21                 if(t > 0) tmp[tot++] = t;
22             } else {
23                 ra += h[i] / x;
24                 int t = h[i] % x;
25                 if(t > 0) tmp[tot++] = t;
26             }
27 
28         } else {
29             tmp[tot++] = h[i];
30         }
31         //if(ra > a) return 0;
32     }
33     sort(tmp, tmp + tot, greater<ll>());
34     for (int i = 0; i < tot; i++) {
35         if(ra < a) {
36             ra++;
37         } else {
38             rb += tmp[i];
39         }
40     }
41     return ra + rb <= b;
42 }
43 void solve() {
44     cin >> n >> a >> b;
45     for (int i = 0; i < n; i++) {
46         cin >> h[i];
47     }
48     sort(h, h + n, greater<ll>());
49     ll left = 1, right = 1e9 + 10;
50     while(left < right) {
51         ll mid = (left + right) / 2;
52         //cout << mid << " " << left << " " << right << endl;
53         if(check(mid)) right = mid;
54         else left = mid + 1;
55 
56     }
57     if(check(left)) cout << left << endl;
58     else cout << -1 << endl;
59 }
60 
61 int main() {
62     //freopen("test.in", "r", stdin);
63     //freopen("test.out", "w", stdout);
64     ios::sync_with_stdio(0);
65     cin.tie(0); cout.tie(0);
66     solve();
67     return 0;
68 }
View Code
原文地址:https://www.cnblogs.com/y119777/p/6861540.html