Deltix Round, Spring 2021( Div. 1 + Div. 2)

A. Game of Life
字符串模拟

毅神代码:

#include<bits/stdc++.h>
using namespace std;
string s;
char ans[1009];
int t ,n, m;
int main()
{
	cin >> t;
	while(t--)
	{
		cin >> n >> m >> s;
		memset(ans,0,sizeof(ans));
		for(int i = 0; i < n; ++i) ans[i] = s[i];
		// 初始化 
		for(int i = 0; i < min(m,n); ++i)// 最多扩散 min(m,n)次 
		{
			for(int j = 0; j < n; ++j)
				if(s[j] == '0')// 每次判断一下0两边的情况 
				{
					int f1 = 0, f2 = 0;
					if(j && s[j-1] == '1') f1 = 1;
					if(j != n-1 && s[j+1] == '1') f2 = 1;
					if(f1&&f2);
					else if(f1 || f2) ans[j] = '1';
				}
			// 因为每次扩散只每次的初始状态有关,所以不能边扩散边改
			for(int j = 0 ; j < n; ++j) s[j] = ans[j];
		}
		ans[n] = '\0';
		printf("%s\n",ans);
	}
	return 0;
}

我的垃圾代码:
和毅神思路不一样,他以死细胞为主,模拟扩散m次
我模拟的扩散的区间,只要能扩散到的都先变成1,最后打个补丁,只有在两个1的位置相加为偶数时,中间的那个死细胞不会激活

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 9;
typedef long long ll;
ll t = 1, n, m, r, k;
vector <pair<int,int> > v, vv;
//ll a[N];
char s[N];
int main()
{
	cin >> t;
	while(t--)
	{
		v.clear();vv.clear();
		cin >> n >> m;
		scanf("%s", s+1);
		for(int i = 1; i <= n; ++i)
		{
			if(s[i] == '1')
			{
				int x, y;
				if(i-m <= 0) x = 1;
				else x = i - m;
				if(i+m > n) y = n;
				else y = i + m;
				v.push_back(make_pair(x, y));
				vv.push_back(make_pair(i-m,i+m));
			}
		}
		if(!v.size())
		{
			printf("%s\n", s+1);continue;
		}
		//for(int i = 0; i < v.size(); ++i)
		//	cout << v[i].first << " " << v[i].second << " ";cout << endl;
		if(v[0].first > 1)
		{
			for(int i = 1; i < v[0].first; ++i) s[i] = '0';
			for(int i = v[0].first; i <= v[0].second; ++i) s[i] = '1';
		}
		else for(int i = 1; i <= v[0].second; ++i) s[i] = '1';
		
		for(int i = 1; i < v.size() - 1; ++i)
		{
			if(v[i].first < v[i-1].second)
			{
				for(int j = v[i-1].second; j <= v[i].second; ++j) s[j] = '1';
			}
			else
			{
				for(int j = v[i-1].second + 1; j < v[i].first; ++j)	s[j] = '0';
				for(int j = v[i].first; j <= v[i].second; ++j)	s[j] = '1';
			}
		}
		if(v.size() > 1 )
		{
				int x = v.size();
				if(v[x-1].first > v[x-2].second)
				{
					for(int i = v[x-2].second + 1; i < v[x-1].first; ++i) s[i] = '0';
					for(int i = v[x-1].first; i <= v[x-1].second; ++i) s[i] = '1';
				}
				else 
					for(int i = v[x-2].second + 1; i <= v[x-1].second; ++i) s[i] = '1';	
		}
		// 打个补丁 
		for(int i = 1; i < vv.size(); ++i)
		{
			if(vv[i-1].second + 1 > vv[i].first)
			{
				int x1 = (vv[i-1].first + vv[i-1].second) / 2;
				int x2 = (vv[i].first + vv[i].second) / 2;
				if((x1+x2) % 2 == 0) s[(x1+x2)/2] = '0';
			}
		}
		printf("%s\n", s+1);
	}
	return 0;
}

B. Lord of the Values
两个操作:
1 a[i] = a[i] + a[j]
2 a[j] = a[j] - a[i]
显然是一道求通解的题目

我们设 a[i] = a, a[j] = b, i < j
初始: a b
选择:1 a+b b
2 a+b -a
1 b -a
2 b -a-b
1 -a -a-b
2 -a -b
经过6次变换即可让两个数变成相反数,

/**
 *    author:  tourist
 *    created: 30.05.2021 17:40:11       
**/
#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int t;
  cin >> t;
  while (t--) 
  {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) 
    {
      int x;
      cin >> x;
    }
    cout << 3 * n << '\n';
    for (int i = 1; i <= n; i += 2) 
    {
      cout << "1 " << i << " " << i + 1 << '\n';
      cout << "2 " << i << " " << i + 1 << '\n';
      cout << "1 " << i << " " << i + 1 << '\n';
      cout << "2 " << i << " " << i + 1 << '\n';
      cout << "1 " << i << " " << i + 1 << '\n';
      cout << "2 " << i << " " << i + 1 << '\n';
    }
  }
  return 0;
}

C. Compression and Expansion
模拟
主要是读懂怎么构造

#include<bits/stdc++.h>
using namespace std;
int ans[1009];
int t, n , x;

int main()
{
	cin >> t;
	while(t--)
	{
		memset(ans,0,sizeof(ans));
		int cnt = 0;
		cin >> n;
		for(int i = 1; i <= n; ++i)
		{
			cin >> x;
			if(x == 1) ans[++cnt] = x;
			else 
			{
				if(x == ans[cnt] + 1) ans[cnt] = x;
				else 
				{
					while(cnt && ans[cnt] != x-1) --cnt;
					ans[cnt] = x;
				}
			}
			for(int i = 1; i <= cnt; ++i)
				cout << ans[i] << ".\n"[i==cnt];
		}
		cout << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值