6803 Blow up the Enemy
难得一见的比赛水题
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int maxn = 1000 + 5;
int T, n, A[maxn], D[maxn];
int main(void) {
scanf("%d", &T);
while (T--){
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d%d", &A[i], &D[i]);
double p = 0, s[maxn] = { 0 };
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
if (A[i] >= 100 && A[j] >= 100) { s[j] += 0.5; continue; }
int t1 = (int)(ceil((100.0 - A[i]) / A[i])) * D[i];
int t2 = (int)(ceil((100.0 - A[j]) / A[j])) * D[j];
if (t1 == t2)s[j] += 0.5;
if (t1 > t2) s[j] += 1;
if (t1 < t2) s[j] += 0;
}
p = s[1];
for (int i = 2; i <= n; i++)
if (p < s[i])p = s[i];
printf("%f\n", p / n);
}
return 0;
}
6805 Deliver the Cake
可以说应该算是个简单题吧,就是在longlong这里捣鼓了好一会儿。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const ll inf = 1e16;
const int N = 4e5 + 5;
int T, n, m, s, t;
int u, v, vis[N][2];
ll w, x, dis[N][2];
char str[N];
struct node {
int to;
ll w;
node() {}
node(int to, ll w) :to(to), w(w) {}
};
struct state {
int id, hand;
ll dis;
state() {}
state(int id, int hand, ll dis) :id(id), hand(hand), dis(dis) {}
bool operator < (const state& B) const { return dis > B.dis; }
}p;
vector<node>e[N];
int main(void) {
scanf("%d", &T);
while (T--) {
scanf("%d %d %d %d %lld", &n, &m, &s, &t, &x);
scanf("%s", str + 1);
for (int i = 1; i <= n; i++) {
vis[i][0] = vis[i][1] = 0;
dis[i][0] = dis[i][1] = inf;
if (str[i] == 'L')vis[i][1] = 1;
if (str[i] == 'R')vis[i][0] = 1;
e[i].clear();
}
for (int i = 0; i < m; i++) {
scanf("%d %d %lld", &u, &v, &w);
e[u].push_back(node(v, w));
e[v].push_back(node(u, w));
}
priority_queue<state>pq;
if (str[s] == 'L')pq.push(state(s, 0, 0));
if (str[s] == 'R')pq.push(state(s, 1, 0));
if (str[s] == 'M') {
pq.push(state(s, 0, 0));
pq.push(state(s, 1, 0));
}
dis[s][0] = dis[s][1] = 0;
while (!pq.empty()){
state u = pq.top(); pq.pop();
vis[u.id][u.hand] = 1;
if (vis[t][0] && vis[t][1])break;
for (int i = 0; i < e[u.id].size(); i++) {
int v = e[u.id][i].to;
ll w = e[u.id][i].w;
if (str[v] == 'L') {
if (vis[v][0])continue;
if (u.hand == 1)w += x;
if (dis[v][0] > u.dis + w) {
dis[v][0] = u.dis + w;
pq.push(state(v, 0, dis[v][0]));
}
}
else if (str[v] == 'R') {
if (vis[v][1])continue;
if (u.hand == 0)w += x;
if (dis[v][1] > u.dis + w) {
dis[v][1] = u.dis + w;
pq.push(state(v, 1, dis[v][1]));
}
}
else {
if (!vis[v][0]) {
if (u.hand == 1)w += x;
if (dis[v][0] > u.dis + w) {
dis[v][0] = u.dis + w;
pq.push(state(v, 0, dis[v][0]));
}
}
w = e[u.id][i].w;
if (!vis[v][1]) {
if (u.hand == 0)w += x;
if (dis[v][1] > u.dis + w) {
dis[v][1] = u.dis + w;
pq.push(state(v, 1, dis[v][1]));
}
}
}
}
}
printf("%lld\n", min(dis[t][0], dis[t][1]));
}
return 0;
}
6806 Equal Sentences
基础DP
#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const ll mod = 1e9 + 7;
int T, n, cnt, a[maxn];
ll dp[maxn][2];
string tmp;
map<string, int>id;
int main(void) {
scanf("%d", &T);
while (T--){
cnt = 0;
scanf("%d", &n);
id.clear();
for (int i = 1; i <= n; i++) {
cin >> tmp;
if (!id.count(tmp))id[tmp] = ++cnt;
a[i] = id[tmp];
dp[i][0] = dp[i][1] = 0;
}
dp[1][0] = 1, dp[1][1] = 0;
for (int i = 2; i <= n; i++) {
dp[i][0] = dp[i - 1][1] + dp[i - 1][0] % mod;
if (a[i] != a[i - 1])dp[i][1] = dp[i - 1][0] % mod;
else dp[i][1] = 0;
}
printf("%lld\n", (dp[n][1] + dp[n][0]) % mod);
}
return 0;
}
6808 Go Running
Dinic算法求二分图最大匹配
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int inf = 0x3f3f3f3f;
struct node {
int to, cap, next;
};
const int maxn = 2e6 + 10;
node e[maxn];
int n, m, start, tend;
int head[maxn];//链式向前星
int cur[maxn];
int depth[maxn];//dinic分层
int cnt, T;
int Q[maxn << 1];
bool bfs() {
memset(depth, -1, sizeof(depth));
memcpy(cur, head, sizeof(cur));
int Thead = 0, Ttail = 0;
Q[Ttail++] = start;
depth[start] = 0;
while (Thead < Ttail) {
int u = Q[Thead];
if (u == tend)return true;
for (int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].to;
if (depth[v] == -1 && e[i].cap > 0) {
//没有分配层数且仍有容量
depth[v] = depth[u] + 1;
Q[Ttail++] = v;
}
}
Thead++;
}
return false;
}
int dfs(int u, int cap) {
if (u == tend)return cap;
int flow = 0, f;
for (int& i = cur[u]; i != -1; i = e[i].next) {
if ((depth[u] + 1 == depth[e[i].to]) && e[i].cap > 0) {
int f = dfs(e[i].to, min(cap - flow, e[i].cap));
if (f > 0) {
e[i].cap -= f;
e[i ^ 1].cap += f;
flow += f;
if (flow == cap)break;
}
}
}
if (!flow)depth[u] = -2;//防止重搜
return flow;
}
void addedge(int u, int v, int w) {
e[cnt].to = v;//u指向的端点
e[cnt].cap = w;//权值
e[cnt].next = head[u];//指向上一条边
head[u] = cnt++;//指向以u为端点的最新一条边
}
int X[maxn], Y[maxn];
int a[maxn], b[maxn];
int main(void) {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
scanf("%d", &T);
while (T--){
scanf("%d", &n);
memset(head, -1, sizeof(head));
cnt = 0;
for (int i = 0; i < n; i++) {
int t, x;
scanf("%d%d", &t, &x);
X[i] = x + t; a[i] = X[i];
Y[i] = x - t; b[i] = Y[i];
}
sort(a, a + n);
int cnta = unique(a, a + n) - a;
sort(b, b + n);
int cntb = unique(b, b + n) - b;
start = cnta + cntb + 5; tend = start + 1;
for (int i = 0; i < n; i++) {//离散化
int pos1 = lower_bound(a, a + cnta, X[i]) - a;
int pos2 = lower_bound(b, b + cntb, Y[i]) - b + cnta + 2;
addedge(pos1, pos2, 1);
addedge(pos2, pos1, 0);
}
for (int i = 0; i < cnta; i++) {
addedge(start, i, 1);
addedge(i, start, 0);
}
for (int i = 0; i < cntb; i++) {
addedge(i + cnta + 2, tend, 1);
addedge(tend, i + cnta + 2, 0);
}
int ans = 0;
while (bfs()){//Dinic算法
ans += dfs(start, inf);
}
printf("%d\n", ans);
}
return 0;
}
6812 Kindergarten Physics
考虑到数据范围,最坏情况a=100,b=100,t0=100距离移动也不超过10^-6,因此直接输出d即可。
#include<cstdio>
using namespace std;
int T;
double a, b, d, t0;
int main(void) {
scanf("%d", &T);
while (T--){
scanf("%lf%lf%lf%lf", &a, &b, &d, &t0);
printf("%f\n", d);
}
return 0;
}
6813 Last Problem
构造题,但是要注意paint的顺序,(n-1)和(n-4)的必须在一条线上,(n-2)和(n-3)在一条线上。
否则可能不合规则,如n=6,在上面n-1,右边n-2,下面n-3,左边n-4的顺序下,在paint右边为4时,4还要继续向右边piant 2,但是此时已经有2在左边了(6要paint的位置上面为5,5的下面是5-3=2)。
#include<cstdio>
#include<cstring>
using namespace std;
int n, dp[205][205];
void paint(int x, int y, int c) {
if (c <= 0)return;
if (dp[x][y + 1] != c - 1)paint(x, y + 1, c - 1);
if (dp[x + 1][y] != c - 2)paint(x + 1, y, c - 2);
if (dp[x - 1][y] != c - 3)paint(x - 1, y, c - 3);
if (dp[x][y - 1] != c - 4)paint(x, y - 1, c - 4);
dp[x][y] = c;
printf("%d %d %d\n", x, y, c);
}
int main(void) {
scanf("%d", &n);
paint(101, 101, n);
return 0;
}