ACM练习坑(待填)

这几天刚到学校,空闲时间比较多,又加入了ACM队,打算重整信心捡起以前的知识,现在就来阅题填坑啦

以下题目来自codeforces

我已经做了:
15/50

Codeforces Round #433 (Div. 1, based on Olympiad of Metropolises)

A.Planning

有n(<=300000)个飞机,第i个飞机原计划在i时刻起飞。现在机场延误,需要让这n个飞机在[ k , k+n ]时刻全部飞完,每个时刻只能飞一个飞机,同时每个飞机不能比原计划更早起飞,也就是飞机i的起飞区间应该是[ i , n+k ]。每个飞机有一个延误系数,这个飞机的延误代价=延误系数*延误时间(如果按照原计划时间起飞则延误代价=0)。求最小延误代价,以及每个飞机的起飞时刻。

贪心很容易想到,但是有时间的限制,算作二维问题

就让当前状态满足一维的限制,另一维取最优即可

即当前加入的都是可选状态。

#include <bits/stdc++.h>
#define maxn 300010
using namespace std;

struct Node {
	int c, id;
} p[maxn];
bool operator < (const Node& a, const Node& b) {
	return a.c < b.c;
}

priority_queue<Node> q;
int n, k;

int main() {
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; ++ i)
		scanf("%d", &p[i].c), p[i].id = i;
	for(int i = 1; i <= k; ++ i)
		q.push(p[i]);
	long long ans = 0;
	for(int i = k+1; i <= k+n; ++ i) {
		if(i <= n) q.push(p[i]);
		Node now = q.top(); q.pop();
		p[now.id].id = i;
		ans += (long long)(i-now.id)*now.c;
	}
	
	printf("%I64d\n", ans);
	for(int i = 1; i <= n; ++ i)
		printf("%d ", p[i].id);
	return 0;
}

B.Jury Meeting

现在有(n+1)个城市,其中第1~n个城市每个城市有一个人,第0个城市是人们需要聚集的地方。还有m条航班,每条航班从0到其他城市或从其他城市到0,当天即可抵达,现在需要选定一个时间段,长度为k天,使得这一个时间段里人们都在0城市工作(航班抵达和离开0城市的那一天不能进行工作),问把n个人送到0城市,工作完成后再送回去的最小花费。

贪心+预处理

#include <bits/stdc++.h>
#define maxn 1000010
using namespace std;


int n, m, k;

struct Node {
	int d, f, t, c;
} p[maxn];
bool operator < (const Node& a, const Node& b) {
	return a.d < b.d;
}

long long ans1[maxn];
long long ans2[maxn];

int vis[maxn];
int cnt;

int main() {
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 1; i <= m; ++ i) 
		scanf("%d%d%d%d", &p[i].d, &p[i].f, &p[i].t, &p[i].c);
		
	sort(p+1, p+1+m);
	memset(ans1, -1, sizeof ans1);
	memset(ans2, -1, sizeof ans2);
	memset(vis, 0, sizeof vis);
	cnt = 0;
	long long sum = 0;
	for(int i = 1; i <= m; ++ i) {
		if(p[i].f) {
			if(vis[p[i].f]) {
				if(p[i].c < vis[p[i].f])
					sum = sum-vis[p[i].f]+p[i].c, vis[p[i].f] = p[i].c;	
			}
			else {
				vis[p[i].f] = p[i].c;
				sum += p[i].c;
				cnt ++;	
			}
		}
		
		if(cnt == n) 
			ans1[p[i].d] = sum;
	}
	
	memset(vis, 0, sizeof vis);
	cnt = 0;
	sum = 0;
	for(int i = m; i; -- i) {
		if(p[i].t) {
			if(vis[p[i].t]) {
				if(p[i].c < vis[p[i].t])
					sum = sum-vis[p[i].t]+p[i].c, vis[p[i].t] = p[i].c;	
			}
			else {
				vis[p[i].t] = p[i].c;
				sum += p[i].c;
				cnt ++;	
			}
		}
		
		if(cnt == n) 
			ans2[p[i].d] = sum;
	}
	
	int mx = 0;
	for(int i = 1; i <= m; ++ i)
		mx = max(mx, p[i].d);
	for(int i = 1; i <= mx; ++ i) 
		if(ans1[i-1] != -1) {
			if(ans1[i] == -1) ans1[i] = ans1[i-1];
			else ans1[i] = min(ans1[i], ans1[i-1]);
		}
			
	for(int i = mx; i; -- i)
		if(ans2[i+1] != -1) {
			if(ans2[i] == -1) ans2[i] = ans2[i+1];
			else ans2[i] = min(ans2[i], ans2[i+1]);
		}
	
	long long ret = -1;
	for(int i = 1; i <= mx-k; ++ i) {
		if(ans1[i] > 0 && ans2[i+k+1] > 0) {
			if(ret == -1) ret = ans1[i]+ans2[i+k+1];
			else ret = min(ret, ans1[i]+ans2[i+k+1]);
		}
	}
	
	printf("%I64d\n", ret);
	return 0;
} 

C.Boredom

主席树,二维前缀和

这样就可以快速的查询某个子矩阵里标记点的个数,对于每个查询的矩阵,我们只需要求不在这个矩阵里的所有 beautiful rectangles个数即可,也就是两个被标记的点都在查询矩阵的上方,下方,左方,右方,最后在去一下重。

#include <bits/stdc++.h>
#define maxn 200005
using namespace std;
typedef long long ll;
int n, q;
int lc[maxn*30], rc[maxn*30], size[maxn*30];
int cnt = 0, t[maxn], p[maxn];

int update(int root, int l, int r, int x, int k) {
	int now = ++ cnt;
	size[now] = size[root] + k;
	if(l == r) return now;
	int mid = l + r >> 1;
	if(x <= mid) {
		lc[now] = update(lc[root], l, mid, x, k);
		rc[now] = rc[root];
	}
	else {
		lc[now] = lc[root];
		rc[now] = update(rc[root], mid+1, r, x, k);
	}
	return now;
}

int query(int root, int l, int r, int L, int R) {
	if(root == 0 || L > R || L < 1 || R > n) return 0;
	if(L == l && R == r)
		return size[root];	
	
	int mid = l + r >> 1;
	if(R <= mid) return query(lc[root], l, mid, L, R);
	if(L > mid) return query(rc[root], mid+1, r, L, R);
	return query(lc[root], l, mid, L, mid)+query(rc[root], mid+1, r, mid+1, R);
}

ll f(int x) { return (ll)x*(x-1)/2; }

int main() {
	scanf("%d%d", &n, &q);
	for(int i = 1; i <= n; ++ i) {
		scanf("%d", &p[i]);
		t[i] = update(t[i-1], 1, n, p[i], 1);
	}

	ll ans = 0;
	int l, d, r, u;
	while(q --) {
		scanf("%d%d%d%d", &l, &d, &r, &u);
		int t1 = query(t[l-1], 1, n, 1, n);
		int t2 = query(t[n], 1, n, 1, d-1);
		int t3 = query(t[n], 1, n, 1, n) - query(t[r], 1, n, 1, n);
		int t4 = query(t[n], 1, n, u+1, n);
		int t5 = query(t[l-1], 1, n, 1, d-1);
		int t6 = t2-query(t[r], 1, n, 1, d-1);
		int t7 = query(t[l-1], 1, n, u+1, n);
		int t8 = query(t[n], 1, n, u+1, n)-query(t[r], 1, n, u+1, n);
		ans = f(n)-(f(t1)+f(t2)+f(t3)+f(t4)-f(t5)-f(t6)-f(t7)-f(t8));
		printf("%I64d\n", ans);
	}


    return 0;  
 }  

  

Codeforces Round #432 (Div. 1, based on IndiaHacks Final Round 2017)

A.需要一些数学脑洞??范围1000??

It's easier to visualize this in 2D first. Fix a point p. If all other points form angles that are 90 degrees or greater, they must all be in different quadrants, so there can be at most 4 such points. In k dimension, this generalizes to 2*k such points, so for five dimensions, there can only be at most 10 other points. Thus, we can run the naive solution for small n and print 0 otherwise.

#include <bits/stdc++.h>
#define maxn 105
using namespace std;

struct Point {
	int x[5];
	void read() {
		for(int i = 0; i < 5; ++ i)
			scanf("%d", &x[i]);
	}
}p[maxn];

long long operator * (const Point& a, const Point& b) {
	long long ret = 0;
	for(int i = 0; i < 5; ++ i)
		ret += (long long)a.x[i]*b.x[i];
	return ret;
}

Point operator - (const Point& a, const Point& b) {
	Point ret;
	for(int i = 0; i < 5; ++ i)
		ret.x[i] = a.x[i] - b.x[i];
	return ret;
}

int n;
bool fg;
vector<int> G;

bool pd(int x, int y, int z) {
	return (p[y]-p[x]) * (p[z]-p[x]) > 0;
}

int main() {
	scanf("%d", &n);
	if(n > 100) {
		printf("0\n");
		return 0; 
	} 
	for(int i = 1; i <= n; ++ i)
		p[i].read();
	for(int i = 1; i <= n; ++ i) {
		fg = true;
		for(int j = 1; j <= n; ++ j) {
			for(int k = j+1; k <= n; ++ k)
				if(i != j && i != k) {
					if(pd(i, j, k)) {
						fg = false;
						break;
					}
				}
			if(!fg) break;
		}
		if(fg) G.push_back(i);
	}
	printf("%d\n", G.size());
	for(int i = 0; i < G.size(); ++ i)
		printf("%d\n", G[i]);
	return 0;
} 

B.Arpa and a list of numbers

枚举因子然后就好做了

#include <bits/stdc++.h>  
using namespace std;
typedef long long ll;  
const int maxn = 2000010;
const ll inf = 1e18;
ll s[maxn];
int a[maxn];
bool used[maxn];

int n;
ll x, y;

int main(){  
    scanf("%d%I64d%I64d", &n, &x, &y);  
    int p = x / y;
    for(int i = 1; i <= n; ++ i) {
    	int t;
    	scanf("%d", &t);
    	a[t] ++;
    	s[t] += t;
	}
   	
	ll ans = inf;
   	for(int i = 1; i < maxn; ++ i)
   		a[i] += a[i-1], s[i] += s[i-1];
   	
	for(int i = 2; i <= 1000000; ++ i) {
		if(used[i]) continue;
		ll tmp = 0;
		for(int j = i; j <= 1000000+i; j += i) {
			used[j] = true;
			int k = max(j-i+1, j-p);
			tmp += ((ll)(a[j]-a[k-1])*j - (s[j]-s[k-1]))*y + (ll)(a[k-1]-a[j-i])*x;
		}
		ans = min(ans, tmp);
	} 
	
	printf("%I64d", ans);
    return 0;  
}  

  

 

2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)

我能说我的A题没看懂嘛。。

B.Minimum and Maximum

This is an interactive problem. You have to use flush operation right after printing each line. For example, in C++ you should use function fflush(stdout)

交互式询问一个数列的最大最小值

两个分成一组查询

#include<bits/stdc++.h>
using namespace std;

char ask(int x, int y) {
	printf("? %d %d\n", x, y);
	fflush(stdout);
	char c;
	cin >> c;
	return c;
} 

void solve() {
	int n;
	cin >> n;
	if(n == 1) {
		printf("! 1 1\n");
		return;
	}
	char c = ask(1, 2);
	int mx, mn;
	if(c == '=') mx = mn = 1;
	if(c == '<') mx = 2, mn = 1;
	if(c == '>') mx = 1, mn = 2;
	for(int i = 3; i <= n; i += 2) {
		if(i == n) {
			if(ask(mx, i) == '<') mx = i;
			if(ask(mn, i) == '>') mn = i;
		}
		else {
			c = ask(i, i+1);
			if(c == '>') {
				if(ask(mx, i) == '<') mx = i;
				if(ask(mn, i+1) == '>') mn = i+1;
			}
			else {
				if(ask(mn, i) == '>') mn = i;
				if(ask(mx, i+1) == '<') mx = i+1;
			}
		}
	}
	printf("! %d %d\n", mn, mx);
	fflush(stdout);
}
	
int main() {
	int Test;
	scanf("%d",&Test);
	
	while (Test--)
		solve();
	
	return 0;
}

C.Bulmart

竟然养成了过了样例就交的坏习惯

小错误不断啊。。

错因是没有开longlong,两数相乘的范围没有看到,最后还写T了。。感觉很绝望

然后把bfs的常数省了省,好像还是不行。

唔。把二分里套的sort省掉以后就A了。。

#include <bits/stdc++.h>
#define maxn 5010
using namespace std;

int n, m;
struct Edge {
	int to, nxt;
}edge[maxn*maxn*2];
int h[maxn], cnt;
void addedge(int u, int v) {
	++ cnt;
	edge[cnt].to = v;
	edge[cnt].nxt = h[u];
	h[u] = cnt;
}

struct qwq { int num, price, dis; } test;
bool operator < (const qwq& a, const qwq& b) {
	return a.price < b.price;
}

vector<pair<int, int> > Gpa[maxn];
vector<qwq> ans;

int G, R, A;

int tim, vis[maxn], que[maxn], dis[maxn];
void bfs() {
	ans.clear();
	int head = 0, tail = 0;
	que[tail ++] = G;
	vis[G] = ++ tim;
	dis[G] = 0;
	while(head != tail) {
		int u = que[head ++];
		for(int i = 0; i < Gpa[u].size(); ++ i) {
			test.dis = dis[u];
			test.num = Gpa[u][i].second;
			test.price = Gpa[u][i].first; 
			ans.push_back(test);
		}
			
		for(int i = h[u]; i; i = edge[i].nxt) {
			int v = edge[i].to;
			if(vis[v] != tim) {
				vis[v] = tim;
				dis[v] = dis[u]+1;
				que[tail ++] = v;
			}
		}
	}
	sort(ans.begin(), ans.end());
}

bool judge(int x) {
	long long nw = 0;
	int r = R;
	for(int i = 0; i < ans.size(); ++ i) {
		qwq& test = ans[i];
		if(test.dis > x) continue;
		if(r > test.num) {
			r -= test.num;
			nw += (long long)test.num*test.price;
			if(nw > A) return false;
		} 
		else {
			nw += (long long)r*test.price;
			if(nw > A) return false;
			else return true;
		}
	}
	return false;
}

void solve() {
	bfs();
	int l = 0, r = n;
	while(l < r) {
		int mid = l + (r-l)/2;
		if(judge(mid)) r = mid;
		else l = mid+1;
	}
	if(l != n)printf("%d\n", l);
	else printf("-1\n");
}

int main() {
	scanf("%d%d", &n, &m);
	int u, v, d, q;
	for(int i = 1; i <= m; ++ i) {
		scanf("%d%d", &u, &v);
		addedge(u, v);
		addedge(v, u);
	}
	scanf("%d", &m);
	for(int i = 1; i <= m; ++ i) {
		scanf("%d%d%d", &u, &v, &d);
		Gpa[u].push_back(make_pair(d, v));
	}
	scanf("%d", &q);
	while(q --) {
		scanf("%d%d%d", &G, &R, &A);
		solve();
	}


	return 0;
}

  

D.Running Over the bridges

感觉像守望者的逃离。。贪心尽量放在后面

#include <bits/stdc++.h>
#define maxn 200010
using namespace std;

vector<long long> ans;
int n;
long long r, l[maxn], t[maxn];

int main() {
	scanf("%d%I64d", &n, &r);
	for(int i = 1; i <= n; ++ i)
		scanf("%I64d", &l[i]);
	for(int i = 1; i <= n; ++ i)
		scanf("%I64d", &t[i]);
	
	long long re = 0, nw = 0, tot = 0;
	for(int i = 1; i <= n; ++ i) {
		if(t[i] < l[i]) {
			printf("-1\n");
			return 0;
		}
		if(re >= l[i]) {
			re -= l[i];
			nw += l[i];
			continue;
		}
		l[i] -= re;
		t[i] -= re;
		nw += re;
		re = 0;
		if(l[i]*2 <= t[i]) 
			nw += l[i]*2;
		else {
			long long T = t[i] - l[i];
			l[i] -= T;
			t[i] -= T*2;
			nw += T*2;
			for(long long j = nw; j < nw+t[i] && ans.size() < 100010; j += r) 
				ans.push_back(j);
			nw += l[i];
			tot += l[i] / r;
			re = l[i] % r;
			if(re) {
				tot ++;
				re = r - re;
			}
		}
	}
	
	if(ans.size() == 0) printf("0\n");
	else {
		printf("%I64d\n", tot);
		if(ans.size() <= 100000) {
			sort(ans.begin(), ans.end());
			for(int i = 0; i < ans.size(); ++ i) 
				printf("%I64d ", ans[i]);
		}
	}
	return 0;
}

E.关于排行榜的滚动,先按照成绩排一个名,d值为正的从得分score小到大搞一下,d值为负的score从大倒小搞一下  

#include <bits/stdc++.h>
#define maxn 110
using namespace std;

int n;
bool vis[maxn];
struct People {
	int val, d, id;
}p[maxn];

bool operator < (const People& a, const People& b) {
	if(a.val != b.val) return a.val > b.val;
	return a.id < b.id;
}
//优先级顺序 

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; ++ i) {
		scanf("%d%d", &p[i].val, &p[i].d);
		p[i].id = i;
	}
		
	sort(p+1, p+1+n);
	int ans = 0;
	for(int i = n; i >= 1; -- i) {
		if(vis[p[i].id]) continue;
		if(p[i].d < 0) continue;
		vis[p[i].id] = 1;
		p[i].val += p[i].d;
		for(int j = i-1; j; -- j) {
			if(p[j+1] < p[j]) {
				ans ++;
				swap(p[j], p[j+1]);
			} else break;
		}
		++ i;
	}
	
	for(int i = 1; i <= n; ++ i) {
		if(vis[p[i].id]) continue;
		vis[p[i].id] = 1;
		p[i].val += p[i].d;
		for(int j = i+1; j <= n; ++ j) {
			if(p[j] < p[j-1]) {
				ans ++;
				swap(p[j-1], p[j]);
			} else break;
		}
		-- i;
	}
	printf("%d\n", ans);
	return 0;
}

G.Car Repair Shop

模拟区间查询  

#include <bits/stdc++.h>
#define maxn 210

using namespace std;

int n, s[maxn], d[maxn];

int judge(int idx, int l, int r) {
	for(int i = 1; i < idx; ++ i)
		if(max(s[i], l) <= min(s[i]+d[i]-1, r))
			return i; 
	return 0;
}

int main() {
	scanf("%d", &n);
	d[0] = 1;
	for(int i = 1; i <= n; ++ i) {
		scanf("%d%d", &s[i], &d[i]);
		int idx = judge(i, s[i], s[i]+d[i]-1);
		if(!idx) continue;
		s[i] = 1;
		idx = judge(i, s[i], s[i]+d[i]-1);
		while(idx) {
			s[i] = s[idx] + d[idx];
			idx = judge(i, s[i], s[i]+d[i]-1);
		}
	}
	for(int i = 1; i <= n; ++ i)
		printf("%d %d\n", s[i], s[i]+d[i]-1);
	return 0;
}

 H.Delete Them

读懂题意是关键

#include <bits/stdc++.h>

using namespace std;

char s[110][110];
int n, m, x;
vector<int> G;
bool vis[110];
char ans[110];

int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++ i) 
		scanf("%s", s[i]+1);
	int len = -1;
	for(int i = 1; i <= m; ++ i) {
		scanf("%d", &x);
		G.push_back(x);
		vis[x] = true;
		if(len == -1) len = strlen(s[x]+1);
		else if(strlen(s[x]+1) != len) {
			printf("No\n");
			return 0;
		}
	}
	
	
	for(int i = 1; i <= len; ++ i) {
		char c = s[G[0]][i];
		int fg = 0;
		for(int j = 1; j < G.size(); ++ j)
			if(s[G[j]][i] != c) {
				ans[i] = '?';
				fg = -1;
				break;
			}
		if(!fg) ans[i] = c;
	}
	
	for(int i = 1; i <= n; ++ i) {
		if(!vis[i] && strlen(s[i]+1) == len) {
			int fg = 0;
			for(int j = 1; j <= len; ++ j) {
				if(ans[j] == '?') continue;
				if(ans[j] != s[i][j]) {
					fg = -1;
					break;
				}
			}
			if(!fg) {
				printf("No");
				return 0;
			} 
		}
	}
	printf("Yes\n");
	for(int i = 1; i <= len; ++ i)
		putchar(ans[i]);
	return 0;
}

I.Olympiad in Programming and Sports

费用流

#include <bits/stdc++.h>
#define maxn 3005
using namespace std;

int n, p, s;
int a[maxn], b[maxn];

struct Edge {
	int to, nxt, w, dis;
}edge[200010];
int h[maxn], cnt = 1, S, T;
void addedge(int u, int v, int w, int dis) {
	++ cnt;
	edge[cnt].to = v;
	edge[cnt].nxt = h[u];
	edge[cnt].w = w;
	edge[cnt].dis = dis;
	h[u] = cnt;
	swap(u, v), dis = -dis, w = 0;
	++ cnt;
	edge[cnt].to = v;
	edge[cnt].nxt = h[u];
	edge[cnt].w = w;
	edge[cnt].dis = dis;
	h[u] = cnt;
}


const int inf = 0x7fffffff/2;
queue<int> Q;
int dis[maxn], pre[maxn], ans;
bool vis[maxn];
bool spfa() {
	for(int i = S; i <= T; ++ i)
		dis[i] = -inf;
	dis[S] = 0;
	Q.push(S);
	while(!Q.empty()) {
		int u = Q.front(); Q.pop(); vis[u] = false;
		for(int i = h[u]; i; i = edge[i].nxt) {
			if(edge[i].w) {
				int v = edge[i].to;
				if(dis[v] < dis[u] + edge[i].dis) {
					dis[v] = dis[u] + edge[i].dis;
					pre[v] = i;
					if(!vis[v]) vis[v] = true, Q.push(v);
				}
			}
		}
	} return dis[T] > 0;
}

void solve() {
	int x = inf;
	for(int i = pre[T]; i; i = pre[edge[i^1].to])
		x = min(x, edge[i].w);
	for(int i = pre[T]; i; i = pre[edge[i^1].to])
		edge[i].w -= x, edge[i^1].w += x;
	ans += x*dis[T];
}
	
void Maxcostflow() {
	while(spfa())
		solve();
}

int main() {
	scanf("%d%d%d", &n, &p, &s);
	for(int i = 1; i <= n; ++ i)
		scanf("%d", &a[i]);
	for(int i = 1; i <= n; ++ i)
		scanf("%d", &b[i]);
	S = 0, T = n+3;
	int A = n+1, B = n+2;
	for(int i = 1; i <= n; ++ i) {
		addedge(S, i, 1, 0);
		addedge(i, A, 1, a[i]);
		addedge(i, B, 1, b[i]);
	}
	
	addedge(A, T, p, 0);
	addedge(B, T, s, 0);
	
	Maxcostflow();
	
	printf("%d\n", ans);
	vector<int> G;
	G.clear();
	for(int i = h[A]; i; i = edge[i].nxt)
		if(edge[i].w == 1) G.push_back(edge[i].to);
	sort(G.begin(), G.end());
	for(int i = 0; i < G.size(); ++ i)
		printf("%d ", G[i]);
	printf("\n");
	G.clear();
	for(int i = h[B]; i; i = edge[i].nxt)
		if(edge[i].w == 1) G.push_back(edge[i].to);
	sort(G.begin(), G.end());
	for(int i = 0; i < G.size(); ++ i)
		printf("%d ", G[i]);
	return 0;
} 

J.Bottles
现在有n个瓶子,每个瓶子容量bi,已经装了ai的水
把所有的水转移到尽量少的瓶子至少需要几个瓶子?
满足上一问的情况下,最少转移多少单位的水?

dp[i][j][k]表示前i个瓶子选了j个瓶子已经装了k体积的水的最大不动的水的体积

#include <bits/stdc++.h>
using namespace std;

int n, need, sum, ans;
int f[110][10010], a[110], b[110];
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; ++ i) {
    	scanf("%d", &a[i]);
    	need += a[i];
	}
    
    for(int i = 1; i <= n; ++ i) {
    	scanf("%d", &b[i]);
    	sum += b[i];
	}
	
	memset(f, -1, sizeof f);
    f[0][0] = 0;
    for(int i = 1; i <= n; ++ i)
    	for(int j = n; j >= 1; -- j)
    		for(int k = sum; k >= b[i]; -- k)
    			if(f[j-1][k-b[i]] != -1)
    				f[j][k] = max(f[j][k], f[j-1][k-b[i]]+a[i]);
    ans = -1;
    for(int i = 1; i <= n; ++ i) {
    	for(int j = need; j <= sum; ++ j)
    		ans = max(ans, f[i][j]);
    	if(ans != -1) {
    		printf("%d %d\n", i, need-ans);
    		break;
		}
	}
    
    return 0;
}

  

  

2008-2009 ACM-ICPC, NEERC, Southern Subregional Contest

以下太难而且没有题解导致此比赛被弃坑回来再填吧

A题通过人数为0

点开比赛pdf并没有发现第一题是A题(纯属脑抽)

写了半天还以为题目很简单,看了样例发现自己题看错了(已扇自己一万次脸

 那我就按照通过人数的顺序来了。。

G.Friends of Friends 

最简单的一题,可惜还wa了,原因是没有sort(眼瞎看不懂英文increasing number)

 

#include <bits/stdc++.h>
#define maxn 51
using namespace std;

bool G[maxn][maxn], vis[maxn];
int n, x, y, num;
int cnt, ans[maxn];

int main() {
	scanf("%d%d", &n, &x);
	for(int i = 1; i <= n; ++ i) {
		scanf("%d", &num);
		for(int j = 1; j <= num; ++ j) {
			scanf("%d", &y);
			if(i != y) G[i][y] = G[y][i] = 1;
		}
	}
	
	for(int i = 1; i <= n; ++ i) {
		if(G[x][i])
			for(int j = 1; j <= n; ++ j)
				if(j != x && G[i][j] && !G[x][j] && !vis[j])
					ans[++ cnt] = j, vis[j] = true; 
	}
	if(cnt == 0) printf("0\n");
	else {
		printf("%d\n", cnt);
		sort(ans+1, ans+1+cnt);
		for(int i = 1; i <= cnt; ++ i)
			printf("%d\n", ans[i]);
	}
	return 0;
} 

  

F.Text Editor

脑子年久失修,10^6想成了10^5

简单的链表,怪不得过得人这么多(放在考场上要罚多少时啊喂)

#include <bits/stdc++.h>
#define maxn 1000010
using namespace std;

char s[maxn], c[maxn];
int nxt[maxn], pre[maxn], cnt;

int main() {
	scanf("%s", s+1);
	int len = strlen(s+1);
	int nw = 1;
	cnt = 1; 
	for(int i = 1; i <= len; ++ i) {
		if(s[i] == 'L' && nw != 1) nw = pre[nw];
		else if(s[i] == 'R' && nxt[nw]) nw = nxt[nw];
		else if(s[i] >= 'a' && s[i] <= 'z'){
			++ cnt;
			c[cnt] = s[i];
			if(nxt[nw]) {
				pre[nxt[nw]] = cnt;
				nxt[cnt] = nxt[nw];
			}
			nxt[nw] = cnt;
			pre[cnt] = nw;
			nw = cnt;
		}
	}
	nw = 1;
	while(true) {
		nw = nxt[nw];
		if(nw)putchar(c[nw]);
		else break;
	}

	return 0;
}

  

未完待续。。

posted @ 2017-09-05 17:21  _Horizon  阅读(291)  评论(0)    收藏  举报