2020 Multi-University Training Contest 4
1002 Blow up the Enemy
-
思路:贪心 选出造成100伤害所需时间最少的武器数量 计算胜率即可
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
const int INF = 0x3f3f3f3f;
int t, n, a, d, cnt, min_;
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t -- ){
min_ = INF, cnt = 0;
cin >> n;
for (int i = 1; i <= n; i ++ ){
cin >> a >> d;
int tmp = 99 / a * d;
if (tmp < min_){
min_ = tmp;
cnt = 1;
}
else if (tmp == min_)
cnt ++ ;
}
cout << 1.0 - (double)1.0 * cnt / (2.0 * n) << "
";
}
return 0;
}
1003 Contest of Rope Pulling
-
思路:裸的01背包 但dp过程中(sum omega_i)最大值可能达到(10^6) 所以可以对数组进行随机排序 缩小背包的大小
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
const int N = 1e3 + 10;
const int M = 1e6 + 10;
const ll INF = -1e15;
int t, n, m;
ll sum, sum1, sum2, min_w, ans;
ll dp1[M], dp2[M];
struct node{
ll w, v;
}a[N], b[N];
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t -- ){
sum = sum1 = sum2 = ans = 0;
dp1[0] = dp2[0] = 0;
cin >> n >> m;
for (int i = 1; i <= n; i ++ ){
cin >> a[i].w >> a[i].v;
sum1 += a[i].w;
}
for (int i = 1; i <= m; i ++ ){
cin >> b[i].w >> b[i].v;
sum2 += b[i].w;
}
random_shuffle(a + 1, a + n + 1);
random_shuffle(b + 1, b + m + 1);
min_w = min(sum1, sum2);
for (int i = 1; i <= min_w; i ++ )
dp1[i] = dp2[i] = INF;
for (int i = 1; i <= n; i ++ ){
sum += a[i].w;
for (int j = sum; j >= a[i].w; j -- )
if (dp1[j - a[i].w] != INF)
dp1[j] = max(dp1[j], dp1[j - a[i].w] + a[i].v);
}
sum = 0;
for (int i = 1; i <= n; i ++ ){
sum += b[i].w;
for (int j = sum; j >= b[i].w; j -- )
if (dp2[j - b[i].w] != INF)
dp2[j] = max(dp2[j], dp2[j - b[i].w] + b[i].v);
}
for (int i = 1; i <= min_w; i ++ )
ans = max(ans, dp1[i] + dp2[i]);
cout << ans << "
";
}
return 0;
}
1004 Deliver the Cake
-
思路:最短路+拆点 对为MIDDLE的城市建立左手点和右手点 然后对相邻的点连边 如果不同就加上耗费x 注意始点和终点也可能拆点
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
typedef pair<ll, int> p;
const int N = 1e5 + 10;
const int M = 2e5 + 10;
const ll INF = 1e18;
int T, n, m, s, t, tot;
int op[N], head[N << 1];
ll x, ans;
ll dis[N << 1];
string str;
struct Edge{
int to, nxt;
ll dist;
}edge[M << 4];
inline void add(int u, int v, ll w){
edge[ ++ tot ].to = v, edge[tot].dist = w, edge[tot].nxt = head[u], head[u] = tot;
edge[ ++ tot ].to = u, edge[tot].dist = w, edge[tot].nxt = head[v], head[v] = tot;
}
inline void dij(int st){
for (int i = 1; i <= 2 * n; i ++ )
dis[i] = INF;
dis[st] = 0;
priority_queue<p, vector<p>, greater<p> > pq;
pq.push({0, st});
while (!pq.empty()){
int u = pq.top().second;
ll dist = pq.top().first;
pq.pop();
if (dis[u] < dist)
continue;
for (int i = head[u]; i; i = edge[i].nxt){
int v = edge[i].to;
ll dist_ = edge[i].dist;
if (dis[v] > dis[u] + dist_){
dis[v] = dis[u] + dist_;
pq.push({dis[v], v});
}
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T -- ){
tot = 0, ans = INF;
memset(head, -1, sizeof(head));
cin >> n >> m >> s >> t >> x >> str;
for (int i = 0; i < str.length(); i ++ ){
if (str[i] == 'L')
op[i + 1] = -1;
else if (str[i] == 'R')
op[i + 1] = 1;
else
op[i + 1] = 0;
}
for (int i = 1; i <= m; i ++ ){
int u, v;
ll w;
cin >> u >> v >> w;
if (op[u] && !op[v])
swap(u, v);
if (!op[u]){
if (!op[v]){
add(u, v, w);
add(u + n, v + n, w);
add(u, v + n, w + x);
add(u + n, v, w + x);
}
else if (op[v] == 1){
add(u, v, w + x);
add(u + n, v, w);
}
else{
add(u, v, w);
add(u + n, v, w + x);
}
}
else{
if (op[u] == op[v])
add(u, v, w);
else
add(u, v, w + x);
}
}
dij(s);
ans = min(ans, min(dis[t], dis[t + n]));
if (!op[s]){
dij(s + n);
ans = min(ans, min(dis[t], dis[t + n]));
}
cout << ans << "
";
}
return 0;
}
1005 Equal Sentences
-
思路:水题
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
int t, n;
int res[N], ans[N];
string s[N];
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t -- ){
res[1] = ans[1] = 1;
cin >> n;
for (int i = 1; i <= n; i ++ )
cin >> s[i];
for (int i = 2; i <= n; i ++ ){
if (s[i] == s[i - 1])
ans[i] = ans[i - 1];
else
ans[i] = (1ll * ans[i - 1] + 1ll * res[i - 1]) % mod;
res[i] = ans[i - 1];
// cout << res[i] << " " << ans[i] << "
";
}
cout << ans[n] << "
";
}
return 0;
}
1007 Go Running
-
思路:每个人的起始点为(x - t)或(x + t) 对这两种情况建边 要用最少的点来覆盖全部的边 问题就转换为了求二分图的最小点覆盖 又因为二分图的最小点覆盖等于二分图的最大匹配 所以用HK算法即可
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
const int N = 1e5 + 10;
int T, n, t, x, na, nb, tot;
int a[N], b[N], aa[N], bb[N], cx[N], cy[N], head[N];
bool vis[N];
struct Edge{
int to, nxt;
}edge[N << 1];
inline void add(int u, int v){
edge[ ++ tot ].to = v, edge[tot].nxt = head[u], head[u] = tot;
edge[ ++ tot ].to = u, edge[tot].nxt = head[v], head[v] = tot;
}
inline bool dfs(int u){
for (int i = head[u]; i != -1; i = edge[i].nxt){
int v = edge[i].to;
if (!vis[v]){
vis[v] = true;
if (cy[v] == -1 || dfs(cy[v])){
cy[v] = u;
cx[u] = v;
return true;
}
}
}
return false;
}
inline int HK(){
int ans = 0;
memset(cx, -1, sizeof(cx));
memset(cy, -1, sizeof(cy));
for (int i = 1; i <= na; i ++ ){
memset(vis, false, sizeof(vis));
if (cx[i] == -1 && dfs(i))
ans ++ ;
}
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T -- ){
tot = 0;
memset(head, -1, sizeof(head));
cin >> n;
for (int i = 1; i <= n; i ++ ){
cin >> t >> x;
a[i] = aa[i] = x - t;
b[i] = bb[i] = x + t;
}
sort(a + 1, a + n + 1), sort(b + 1, b + n + 1);
na = unique(a + 1, a + n + 1) - a - 1, nb = unique(b + 1, b + n + 1) - b - 1;
for (int i = 1; i <= n; i ++ ){
int u = lower_bound(a + 1, a + 1 + na, aa[i]) - a, v = lower_bound(b + 1, b + 1 + nb, bb[i]) - b + na;
add(u, v);
}
cout << HK() << "
";
}
return 0;
}
1011 Kindergarten Physics
-
思路:水题 万有引力常数太小 可忽略不计
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
int t, a, b, d, t0;
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t -- ){
cin >> a >> b >> d >> t0;
cout << d << "
";
}
return 0;
}
1012 Last Problem
-
思路:构造题 在(x,y)处填val 则必须要在周围填val - 1, val - 2, val - 3, val - 4 dfs按左上右下分别是val - 4, val - 2, val - 1, val - 3来构造即可
-
AC代码
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll mult_mod(ll x, ll y, ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
ll pow_mod(ll a, ll b, ll p){
ll res = 1;
while (b){
if (b & 1)
res = mult_mod(res, a, p);
a = mult_mod(a, a, p);
b >>= 1;
}
return res % p;
}
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
const int N = 1010;
int n;
int mp[N][N];
inline void dfs(int x, int y, int val){
if (val <= 0)
return ;
if (mp[x + 1][y] != val - 1)
dfs(x + 1, y, val - 1);
if (mp[x][y + 1] != val - 2)
dfs(x, y + 1, val - 2);
if (mp[x][y - 1] != val - 3)
dfs(x, y - 1, val - 3);
if (mp[x - 1][y] != val - 4)
dfs(x - 1, y, val - 4);
mp[x][y] = val;
cout << x << " " << y << " " << val << "
";
}
int main(){
#ifndef ONLINE_JUDGE
freopen("my_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
dfs(100, 100, n);
return 0;
}