2020 计蒜之道 预赛 第一场 爆零记

爆零记

  • 本来都忘了有这个比赛emmm
    然后下午其实也没时间写的样子,
    可是一直发短信提醒,,
    所以最后还是抽了小半个小时敲了两份模板
  • 但是,,大概是我菜把,
    两份都只能过样例。。。。
    而且也调试不出个所以然来
    包括拿到题解都觉得我思路没啥问题。。

T1、五子棋

  • 题意:给出一个五子棋盘,判断下一步能不能赢,下哪里能赢。
  • 根据棋子数量可以得知下一步谁下棋。然后枚举每个位置判断能否获胜即可。复杂度O(25*25*5)感觉挺稳的,可是不知道为啥只过了样例
//WA
#include
#include
using namespace std;
char c[50][50];
int main(){
     
	int numo = 0, numx = 0;
	for(int i = 1; i <= 25; i++){
     
		for(int j = 1; j <= 25; j++){
     
			c[i][j] = getchar();
			if(c[i][j]=='o') numo++;
			if(c[i][j]=='x') numx++;
		}
		getchar();
	}
	//cout<
	char ch;
	if(numo==numx)ch = 'x';
	else ch = 'o';
	int ok = 1;
	for(int i = 1; i <= 25; i++){
     
		for(int j = 1; j <= 25; j++){
     
			int ii, jj, cnt;
			//shang
			jj = j, cnt = 1;
			while(c[i][--jj]==ch)cnt++;
			jj = j;
			while(c[i][++jj]==ch)cnt++;
			if(cnt>=5){
     
				cout<<i-1<<" "<<j-1<<"\n";
				ok = 0;
			}
			//zuo
			ii = i, cnt = 1;
			while(c[--ii][j]==ch)cnt++;
			ii = i;
			while(c[++ii][j]==ch)cnt++;
			if(cnt>=5){
     
				cout<<i-1<<" "<<j-1<<"\n";
				ok = 0;
			}
			//zuoshang
			ii = i, jj = j, cnt = 1;
			while(c[--ii][--jj]==ch)cnt++;
			ii = i, jj = j;
			while(c[++ii][++jj]==ch)cnt++;
			if(cnt>=5){
     
				cout<<i-1<<" "<<j-1<<"\n";
				ok = 0;
			}
			//youshang
			ii = i, jj = j, cnt = 1;
			while(c[--ii][++jj]==ch)cnt++;
			ii = i, jj = j;
			while(c[++ii][--jj]==ch)cnt++;
			if(cnt>=5){
     
				cout<<i-1<<" "<<j-1<<"\n";
				ok = 0;
			}
		}
	}
	if(ok)cout<<"tie\n";
	return 0;
}


//AC
#include 
#define IO_OP std::ios::sync_with_stdio(0); std::cin.tie(0);
#define F first
#define S second
#define V vector
#define PB push_back
#define MP make_pair
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define debug(x) cerr << "Line(" << __LINE__ << ") -> " << #x << " is " << x << endl

using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
typedef V<int> vi;

const int INF = 1e9 + 7;

char a[25][25], who;

bool yes() {
     
	for(int i = 0; i <= 20; i++) {
     
		for(int j = 0; j < 25; j++) {
     
			bool ok = true;
			for(int k = 0; k < 5; k++)
				if(a[i+k][j]!=who) ok = false;
			if(ok) return true;
		}
	}
	for(int i = 0; i < 25; i++) {
     
		for(int j = 0; j <= 20; j++) {
     
			bool ok = true;
			for(int k = 0; k < 5; k++)
				if(a[i][j+k]!=who) ok = false;
			if(ok) return true;
		}
	}
	for(int i = 0; i <= 20; i++) {
     
		for(int j = 0; j <= 20; j++) {
     
			bool ok = true;
			for(int k = 0; k < 5; k++)
				if(a[i+k][j+k]!=who) ok = false;
			if(ok) return true;
		}
	}
	for(int i = 4; i < 25; i++) {
     
		for(int j = 0; j <= 20; j++) {
     
			bool ok = true;
			for(int k = 0; k < 5; k++)
				if(a[i-k][j+k]!=who) ok = false;
			if(ok) return true;
		}
	}
	return false;
}

signed main()
{
     
	IO_OP;
	int cnt = 0;
	for(int i = 0; i < 25; i++)
		for(int j = 0; j < 25; j++) {
     
			cin >> a[i][j];
			if(a[i][j] != '.') cnt++;
		}
	who = 'x';
	if(cnt&1) who = 'o';
	bool y = 0;
	for(int i = 0; i < 25; i++) {
     
		for(int j = 0; j < 25; j++) {
     
			if(a[i][j] == '.') {
     
				a[i][j] = who;
				if(yes()) {
     
					cout << i << " " << j << endl;
					y = 1;
				}
				a[i][j] = '.'; 
			}
		}
	}
	if(!y) cout << "tie" << endl;

}



T2、染色(简单)

  • 题意:给出一个长为n的序列,以及m段区间。对序列的每个元素染色成黑或白分别可以获得bi和wi的美感,若某区间染成相同则可额外获得ci的美感,求美感最大。
  • 考虑没有区间的情况,直接扫一遍统计bi和wi单个元素最大即可。而加上区间则意味着有可能获得更高的美感,即当区间全染白+ci>区间染最大的时候,用后者更新即可。用前缀和维护可以O(1)求区间和,直接统计即可。整体复杂度是O(n)的,常数比较大,应该能过。
//WA
#include
#include
using namespace std;
const int maxn = 300050;
typedef long long LL;
int n, m, b[maxn], w[maxn], x[maxn];
LL sb[maxn], sw[maxn], sx[maxn];
int main(){
     
	cin>>n>>m;
	for(int i = 1; i <= n; i++){
     
		cin>>b[i];
		sb[i] = sb[i-1]+b[i];
	}
	for(int i = 1; i <= n; i++){
     
		cin>>w[i];
		x[i] = max(b[i],w[i]);
		sw[i] = sw[i-1]+w[i];
		sx[i] = sx[i-1]+x[i];
	}
	int ans = sx[n];
	for(int i = 1; i <= m; i++){
     
		int t, l, r, c;
		cin>>t>>l>>r>>c;
		if(t==1){
     
			int tmp = sb[r]-sb[l-1];
			if(tmp+c>sx[r]-sx[l-1]){
     
				ans = ans-(sx[r]-sx[l-1])+tmp+c;
			}
		}
		if(t==2){
     
			int tmp = sw[r]-sw[l-1];
			if(tmp+c>sx[r]-sx[l-1]){
     
				ans = ans-(sx[r]-sx[l-1])+tmp+c;
			}
		}
	}
	cout<<ans;
	return 0;
}

//AC
#include 
#define IO_OP std::ios::sync_with_stdio(0); std::cin.tie(0);
#define F first
#define S second
#define V vector
#define PB push_back
#define MP make_pair
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define debug(x) cerr << "Line(" << __LINE__ << ") -> " << #x << " is " << x << endl
#define int ll

using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
typedef V<int> vi;

const int INF = 1e9 + 7, N = 3e5 + 7;

int b[N], w[N], bsum[N], wsum[N], mx[N], sum[N], yes[N];

signed main()
{
     
	IO_OP;

	int n, m;
	cin >> n >> m;
	for(int i = 1; i <= n; i++) {
     
		cin >> b[i];
		bsum[i] = bsum[i - 1] + b[i];
	}
	for(int i = 1; i <= n; i++) {
     
		cin >> w[i];
		wsum[i] = wsum[i - 1] + w[i];
	}
	for(int i = 1; i <= n; i++) {
     
		mx[i] = max(b[i], w[i]);
		sum[i] = mx[i] + sum[i - 1];
	}
	int ans = 0;
	for(int i = 1; i <= m; i++) {
     
		int t, l, r, c;
		cin >> t >> l >> r >> c;
		for(int j = l; j <= r; j++) yes[j] = 1;
		int cur = sum[r] - sum[l-1];
		if(t == 1) {
     
			cur = max(cur, bsum[r] - bsum[l-1] + c);
		} else {
     
			cur = max(cur, wsum[r] - wsum[l-1] + c);
		}
		ans += cur;
	}
	for(int i = 1; i <= n; i++) if(!yes[i]) ans += mx[i];
	cout << ans << endl;

}


//AC
#include 
#define IO_OP std::ios::sync_with_stdio(0); std::cin.tie(0);
#define F first
#define S second
#define V vector
#define PB push_back
#define MP make_pair
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define debug(x) cerr << "Line(" << __LINE__ << ") -> " << #x << " is " << x << endl
#define int ll

using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
typedef V<int> vi;

const int INF = 1e9 + 7, N = 3e5 + 7;

int b[N], w[N], bsum[N], wsum[N], mx[N], sum[N], yes[N];

signed main()
{
     
	IO_OP;

	int n, m;
	cin >> n >> m;
	for(int i = 1; i <= n; i++) {
     
		cin >> b[i];
		bsum[i] = bsum[i - 1] + b[i];
	}
	for(int i = 1; i <= n; i++) {
     
		cin >> w[i];
		wsum[i] = wsum[i - 1] + w[i];
	}
	for(int i = 1; i <= n; i++) {
     
		mx[i] = max(b[i], w[i]);
		sum[i] = mx[i] + sum[i - 1];
	}
	int ans = 0;
	for(int i = 1; i <= m; i++) {
     
		int t, l, r, c;
		cin >> t >> l >> r >> c;
		for(int j = l; j <= r; j++) yes[j] = 1;
		int cur = sum[r] - sum[l-1];
		if(t == 1) {
     
			cur = max(cur, bsum[r] - bsum[l-1] + c);
		} else {
     
			cur = max(cur, wsum[r] - wsum[l-1] + c);
		}
		ans += cur;
	}
	for(int i = 1; i <= n; i++) if(!yes[i]) ans += mx[i];
	cout << ans << endl;

}



T3、染色(中等)

2020 计蒜之道 预赛 第一场 爆零记_第1张图片

//T3
#include 
#define IO_OP std::ios::sync_with_stdio(0); std::cin.tie(0);
#define F first
#define S second
#define V vector
#define PB push_back
#define MP make_pair
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define debug(x) cerr << "Line(" << __LINE__ << ") -> " << #x << " is " << x << endl
#define int ll

using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
typedef V<int> vi;

const int INF = 1e9 + 7, N = 3e5 + 7;

int b[N], w[N], bsum[N], wsum[N], mx[N], sum[N], dp[N];
V<pi> bb[N], ww[N];


int bmore[N], wmore[N];

signed main()
{
     
	IO_OP;

	int n, m;
	cin >> n >> m;
	for(int i = 1; i <= n; i++) {
     
		cin >> b[i];
		bsum[i] = bsum[i - 1] + b[i];
	}
	for(int i = 1; i <= n; i++) {
     
		cin >> w[i];
		wsum[i] = wsum[i - 1] + w[i];
	}
	for(int i = 1; i <= n; i++) {
     
		mx[i] = max(b[i], w[i]);
		sum[i] = mx[i] + sum[i - 1];
	}
	vi v;
	v.PB(1), v.PB(n+1);
	for(int i = 0; i < m; i++) {
     
		int t, l, r, c;
		cin >> t >> l >> r >> c;
		if(t == 1) {
     
			bb[r].EB(l, c);
		} else {
     
			ww[r].EB(l, c);
		}
		v.PB(l);
		v.PB(r+1);
	}
	sort(ALL(v));
	v.resize(unique(ALL(v))-v.begin());
	int nn = v.size() - 1;
	auto getmx = [&](int l, int r) {
     
		int lb = v[l], rb = v[r + 1] - 1;
		return sum[rb] - sum[lb-1];
	};
	auto getb = [&](int l, int r) {
     
		int lb = v[l], rb = v[r + 1] - 1;
		return bsum[rb] - bsum[lb-1];
	};
	auto getw = [&](int l, int r) {
     
		int lb = v[l], rb = v[r + 1] - 1;
		return wsum[rb] - wsum[lb-1];
	};
	for(int i = 0; i < nn; i++) {
     
		int r = v[i + 1] - 1;
		for(auto p:bb[r]) {
     
			// bbit.add(p.F, p.S);
			bmore[p.F] += p.S;
		}
		for(auto p:ww[r]) {
     
			// wbit.add(p.F, p.S);
			wmore[p.F] += p.S;
		}
		dp[i] = (i-1 < 0 ? 0 : dp[i-1]) + getmx(i, i);
		int more = 0;
		for(int j = i; j >= 0; j--) {
     
			more += bmore[v[j]];
			dp[i] = max(dp[i], (j-1 < 0 ? 0 : dp[j-1]) + getb(j, i) + more);
		}
		more = 0;
		for(int j = i; j >= 0; j--) {
     
			more += wmore[v[j]];
			dp[i] = max(dp[i], (j-1 < 0 ? 0 : dp[j-1]) + getw(j, i) + more);
		}
	}
	cout << dp[nn-1] << endl;

}


你可能感兴趣的:(算法)