2019CSP-S模拟赛

2019CSP-S模拟赛

于2020/4,2020/7/24两测

作为疫情期间学习过的证据

T1

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>

using namespace std;

long long T;

int xx[5010], yy[5010], xt, yt;
long long ansx, ansy;

string s;

int main(){
	freopen("robot.in","r",stdin);
	freopen("robot.out","w",stdout);
	cin >> s;
//	cout << s << endl;
//	scanf("%s",s+1);
	for(int i = 1; i <= s.size(); i++){
		if(s[i-1] == 'E'){
			xx[i] = xx[i - 1] + 1;
			yy[i] = yy[i - 1];
		}
		else if(s[i-1] == 'W'){
			xx[i] = xx[i - 1] - 1;
			yy[i] = yy[i - 1];
		} 
		else if(s[i-1] == 'N'){
			yy[i] = yy[i - 1] + 1;
			xx[i] = xx[i - 1];
		}
		else if(s[i-1] == 'S'){
			yy[i] = yy[i - 1] - 1;
			xx[i] = xx[i - 1];
		}
//		cout << xx[i] << " " << yy[i] << endl;
	}
	cin >> T;
	xt = xx[s.size()];
	yt = yy[s.size()];
	ansx += T / s.size() * xt;
	ansy += T / s.size() * yt;
	ansx += xx[T % s.size()];
	ansy += yy[T % s.size()];
	printf("%lld %lld
", ansx, ansy); 
	return 0;
}

T2

矩阵快速幂

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#define ll long long
#define MOD 1000000007
using namespace std;

int t;
ll n;

struct mat{
	ll m[4][4];
	mat(){
		memset(m, 0, sizeof(m));
	}
	void base(){
		m[1][3] = 1;
		m[2][1] = 1;
		m[3][2] = 1;
		m[3][3] = 1;
	}
	void pre(){
		m[1][1] = 1;
		m[2][2] = 1;
		m[3][3] = 1;
	}
};

mat operator *(mat a, mat b){
	mat res;

	for(int i = 1; i <= 3; i++){
		for(int j = 1; j <= 3; j++){
			for(int k = 1; k <= 3; k++){
				res.m[i][j] += a.m[i][k] * b.m[k][j];
				res.m[i][j] %= MOD;
			}
		}
	}
	return res;
}
/*
void print(mat a){
	for(int i = 1; i <= 3; i++){
		for(int j = 1; j <= 3; j++)		cout << a.m[i][j] << " ";
		cout << endl;
	}
}
*/
mat ksm(ll num){
	mat ans, a;
	ans.pre();
	a.base();
	while(num){
		if(num & 1){
			ans = ans * a;
		}
		num >>= 1;
		a = a * a;
/*		print(ans);
		printf("
");
		print(a);
		printf("
");
*/	}
	return ans;
}
int main(){
	freopen("seq.in","r",stdin);
	freopen("seq.out","w",stdout);
	scanf("%d",&t);
	while(t--){
		scanf("%lld",&n);
		if(n <= 3){
			printf("1
");
		}
		else{
			mat ans = ksm(n - 3);
//			print(ans);
			ll Ans = 0;
			Ans += ans.m[1][3];
			Ans %= MOD;
			Ans += ans.m[2][3];
			Ans %= MOD;
			Ans += ans.m[3][3];
			Ans %= MOD;
			printf("%lld
", Ans); 
		}
	
	}
	return 0;
}

T3

对n个点分别建黑白两点。

停留1秒转化为从一种颜色的点走到本点的另一颜色的点。

跑最短路即可。

注意迷惑的题目描述。

u->v是从一秒前的u到一秒后的v,但是影响k值的颜色状态全部取一秒之前。

停留,停留一秒后的颜色决定是否加s[i]。

做题历程:

3个月前第一次做:这什么玩意

3个月前听WZ讲:WOW,强!妙!

3个月前听完后自己写:

根据题意建图,跑一遍spfa完事

搞成2n个点,前n个白,后n个黑

对于u,v,k

颜色一样,add(u,v,k);add(u+n,v+n,k);

颜色不一样, add(u,v+n,k-);add(u+n,v,k+)

处理完后,自己的黑白两点相连

add(i,i+n,s[i]);add(i+n,i,0);

spfa(1)
spfa(1+n)

ans=min(dist[n],dist[n*2])

我的程序怎么了呜呜呜调不出来

OH,好,我发现当年真是没有完全懂,程序写的也不对。

3个月后,80pts。

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;

const int maxn = 5010, maxm = 30010;

struct Edge{
	int to, nxt;
	ll k;
}ed[maxm * 2 + maxn * 2];

int n, m, first[maxn * 2], en,  u, v;
ll k, w[maxn], s[maxn];

bool col[maxn * 2];

inline int read(){
	int res = 0;
	char c = getchar();
	while(c < '0' || c > '9'){
		c = getchar();
	}
	while(c <= '9' && c >= '0'){
		res *= 10;
		res += c - '0';
		c = getchar();
	}
	return res;
}
inline ll llread(){
	ll res = 0;
	char c = getchar();
	while(c < '0' || c > '9'){
		c = getchar();
	}
	while(c <= '9' && c >= '0'){
		res *= 10;
		res += c - '0';
		c = getchar();
	}
	return res;
}
void add(int u, int v, ll k){
	ed[++en].to = v;
	ed[en].k = k;
	ed[en].nxt = first[u];
	first[u] = en;
}
ll dist[maxn * 2];
bool inque[maxn * 2];
priority_queue <pair <int, int> > q;
void dijkstra(int s){
	memset(dist, 0x3f, sizeof(dist));
	dist[s] = 0;
	inque[s] = 1;
	q.push(make_pair(0,s));
	while(q.size()){
		int u = q.top().second;
		q.pop();
		for(int e = first[u]; e; e = ed[e].nxt){
			int v = ed[e].to;
			if(dist[v] > dist[u] + ed[e].k){
				dist[v] = dist[u] + ed[e].k;
				if(!inque[v]){
					q.push(make_pair(-dist[v], v));
				}
			}
		}
	}
}
//完成后2mins,只看 
int main(){
	freopen("holes.in","r",stdin);
	freopen("holes.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; i++){
		col[i] = read();
		col[i + n] = !col[i];
	}
//	for(int i = 1; i <= n + n; i++)	cout << col[i] << " ";
//	cout << endl;
	for(int i = 1; i <= n; i++){
		w[i] = llread();
	}
	for(int i = 1; i <= n; i++){
		s[i] = llread();
		if(col[i] == 0)//白洞
		{
			add(i, i + n, s[i]);
			add(i + n, i, 0); 
		} 
		else {
			add(i, i + n, 0);
			add(i + n, i, s[i]);
		}
	}
	for(int i = 1; i <= m; i++){
		u = read(); v = read();
		k = llread();
//		scanf("%lld",&k);
		if(col[u] == 0 && col[v] == 0)//w->b  w-w
		{
			add(u, v + n, k);
			add(u + n, v, k);
//			add(u, v + n, (k - abs(w[u] - w[v]) )>= 0 ? (k - abs(w[u] - w[v]) ): 0); 
//			add(u + n, v, k + abs(w[u] - w[v]));
		} 
		else if(col[u] == 0 && col[v] == 1)//w->w w-b
		{
			add(u, v + n, (k - abs(w[u] - w[v]) )>= 0 ? (k - abs(w[u] - w[v]) ): 0); 
			add(u + n, v, k + abs(w[u] - w[v]));
//			add(u, v + n, k);
//			add(u + n, v, k);
		}
		else if(col[u] == 1 && col[v] == 0)//b->b  b-w
		{
			add(u, v + n, k + abs(w[u] - w[v]));	
			add(u + n, v, (k - abs(w[u] - w[v]) )>= 0 ? (k - abs(w[u] - w[v]) ): 0);

//			add(u, v + n, k);
//			add(u + n, v, k);
		}
		else if(col[u] == 1 && col[v] == 1)//b->w  b-b
		{
			add(u, v + n, k);
			add(u + n, v, k);
			
//			add(u, v + n, k + abs(w[u] - w[v]));	
//			add(u + n, v, (k - abs(w[u] - w[v]) )>= 0 ? (k - abs(w[u] - w[v]) ): 0);
		} 
	}
	dijkstra(1);
	ll ans;
	if(dist[n] < dist[n + n])	ans = dist[n];
	else ans = dist[n + n];
	printf("%lld
",ans);
	return 0;
}

"%lld"!!!!!!!

原文地址:https://www.cnblogs.com/ZhengkunJia/p/13372967.html