[20181103][模拟赛]

题面

T1

思路

因为0的个数超过了一半,所以只要将拍完序后,最中间的数到想得到的中位数之间的每个数都变成S即可。

代码

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100000 + 100;
ll read() {
	ll x = 0, f = 1;
	char c = getchar();
	while(c < '0' || c > '9') {
		if(c == '-') f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9') {
		x = x * 10 + c - '0';
		c = getchar();
	}
	return x * f;
}
ll ans;
ll a[N];
int main() {
	freopen("median.in","r",stdin);
	freopen("median.out","w",stdout);
	int n = read();
	ll s = read();
	for(int i = 1;i <= n;++i) a[i] = read();
	sort(a + 1,a + n + 1);
	for(int i = n/2 + 1;i <= n;++i) {
		if(a[i] >= s) break;
		ans += s - a[i]; 
	}
	cout<<ans;
	return 0;
}

T2

60分思路

对于前60分,可以直接(n^2)dp。用f[i][j]表示前i天,其中j天写了作业的方案数。这样没写作业的天数就是i-j,根据要求((i-j)-j<k => j >i-k)只要控制一下转移的边界就行了。

100分思路

对于一百分,$$C({2n}^n) - C({2n}^{n+k})$$

然后分解质因数求组合数。

60分代码

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1000000 + 100;
int mod;
ll read() {
	ll x = 0, f = 1;
	char c = getchar();
	while(c < '0' || c > '9') {
		if(c == '-') f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9') {
		x = x * 10 + c - '0';
		c = getchar();
	}
	return x * f;
}
int n, K;
namespace BF1 {
	ll f[2010][2010];
	void Main() {
		f[0][0] = 1;
		for(int i = 1;i <= n * 2;++i) {
			if(i < K) f[i][0] = 1;
			for(int j = max(((i - K)/2 + 1),1);j <= min(i,n);++j) {
				f[i][j] = f[i - 1][j] + f[i - 1][j - 1];
				f[i][j] >= mod ? f[i][j] -= mod : 0;
			}
		}
		cout<<f[n * 2][n];
		return;	
	}

}
int ff[N];
int main() {
	freopen("term.in","r",stdin);
	freopen("term.out","w",stdout);
	n = read(), K = read();
	mod = read();
	if(n <= 1000) {
		BF1::Main();
		return 0;
	}
	return 0;
}

T3

思路

将所有的点点权全都放到边上去。然后建个反图,找出S可以到达的边集与T可以到达的边集的交集。然后将答案拆位从高到低贪心。用bitset优化一下。就可以在两秒里跑过了

代码

//2.424s
//2.211s
//2.121s
//2.013s
//1.917s
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cstring>
#include<queue>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 200000 + 100,M = 500000 + 100;
bitset<M>s,t,tmp;
char buf[100000],*_p1 = buf,*_p2 = buf;
#define nc() (_p1==_p2&&(_p2=(_p1=buf)+fread(buf,1,100000,stdin),_p1==_p2) ? EOF :*_p1++)
inline int read() {
	int x=0,f=1;
	char ch=nc();
	for(; !isdigit(ch); ch=nc())if(ch=='-')f=-1;
	for (; isdigit(ch); ch=nc())x=x*10+ch-'0';
	return x*f;
}
struct node {
	int v,nxt;
}e[3][M];
int a[N];
int head[3][N],ejs[3];
int vis[N];
int n,m,S,T;
queue<int>q,q2;
inline void bfsS() {
	while(!q.empty()) q.pop();
	q.push(S);
	memset(vis,0,sizeof(vis));
	vis[S] = 1;
	while(!q.empty()) {
		int u = q.front();q.pop();
		for(int i = head[1][u];i;i = e[1][i].nxt) {
			int v = e[1][i].v;
			s[i] = 1;
			if(vis[v]) continue;
			vis[v] = 1;
			q.push(v);
		}
	}
}
inline void bfsT() {
	while(!q.empty()) q.pop();
	q.push(T);
	memset(vis,0,sizeof(vis));
	while(!q.empty()) {
		int u = q.front();q.pop();
		for(int i = head[2][u];i;i = e[2][i].nxt) {
			int v = e[2][i].v;
			t[i] = 1;
			if(vis[v]) continue;
			vis[v] = 1;
			q.push(v);
		}
	}
}
int W[M];
int vis2[N],vis1[N];
inline void bfs1() {
	while(!q.empty()) {
		int u = q.front();q.pop();
		for(int i = head[1][u];i;i = e[1][i].nxt) {
			int v = e[1][i].v;
			tmp[i] = 1;
			if(vis1[v] == 1) continue;
			vis1[v] = 1;
			q.push(v);
		}
	}
}
inline void bfs2() {
	while(!q2.empty()) {
		int u = q2.front();q2.pop();
		for(int i = head[2][u];i;i = e[2][i].nxt) {
			int  v = e[2][i].v;
			tmp[i] = 1;
			if(vis2[v] == 1) continue;
			vis2[v] = 1;
			q2.push(v);
		}
	}
}
int main() {
	freopen("rabbit.in","r",stdin);
//	freopen("rabbit.out","w",stdout);
	n = read(),m = read(),S = read(),T = read();
	for(int i = 1;i <= n;++i) a[i] = read();
	for(int i = 1;i <= m;++i) {
		int u = read(),v = read(),w = read();
		e[1][i].v = v;e[1][i].nxt = head[1][u];head[1][u] = i;
		e[2][i].v = u;e[2][i].nxt = head[2][v];head[2][v] = i;
		W[i] = a[u] & a[v] & w;
	}
	if(S == T) {
		printf("%d",a[S]);
		return 0;
	}
	bfsS();
	bfsT();
	tmp = s & t;
	if(!tmp.count()) {
		puts("-1");return 0;
	}
	for(int i = 1;i <= m;++i) {
		if(tmp[i] && W[i] == 0) {
			puts("0");
			return 0;
		}
	}
	int ans = 0;
	for(int i = 30;i >= 0;--i) {
		memset(vis1,0,sizeof(vis1));
		memset(vis2,0,sizeof(vis2));
		int bz = 0;
		for(int j = 1;j <= m;++j) {
			if(tmp[j] == 0) continue;
			if(!(W[j] & (1<<i))) {
				bz = 1;
				if(!vis1[e[1][j].v]) {
					q.push(e[1][j].v);
					vis1[e[1][j].v] = 1;
				}
				if(!vis2[e[2][j].v]) {
					q2.push(e[2][j].v);
					vis2[e[2][j].v] = 1;
				}
			}
		}
		if(bz == 0) {
			ans |= (1<<i);
			continue;
		}
		for(int j = 1;j <= m;++j)if((W[j] & (1 << i))) tmp[j] = 0;
		bfs1();
		bfs2();
		tmp = tmp & s  & t;
	}
	cout<<ans;
	return 0;
}

总结

期望得分100 + 60 + 100 = 260
实际得分100 + 60 + 100 = 260

一言

越是代自己辩护,越是暴露自己的过错。 ——红与黑

原文地址:https://www.cnblogs.com/wxyww/p/9901072.html