CF Div.4 Round 806

CF Div.4 Round 806传送门

Share a particularly sentence from my friend:

If you think it's hard, it means you're going up the hill again!😊🌻

A.YES or YES?

题意

会给你一个字符串 只要表示 yes 不管大小写都可以输出Yes 否则No

思路

题意即题解

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
//#define double long double
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m, cnt;
int a[N];
 
void solve()
{
	string st; cin >> st;
	if (st[0] == 'Y' || st[0] == 'y')
	{
		if (st[1] == 'E' || st[1] == 'e')
		{
			if (st[2] == 'S' || st[2] == 's')
			{
				cout << "YES" << endl;
				return;
			}
		}
	}
	cout << "NO" << endl;
}
 
signed main()
{
	IOS;
	int tt = 1; cin >> tt;
	while (tt--) solve();
	return 0;
}

B. ICPC Balloons

题意

ICPC区域赛AC一题会发一个气球,全场第一个做对的会额外发一个,那么给一个字符串代表全场一共做出来了哪几题,要你统计一共发了多少个气球

思路

找个 bool st[26]记录哪个字符第一次出现过则+2,其他+1即可

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m, cnt;
int a[N];
bool ad[300];
void solve()
{
	memset(ad, false, sizeof ad);
	int n; cin >> n;
	string st; cin >> st;
	int cnt = 0;
	for (int i = 0; i < n; i++)
	{
		if (ad[st[i]] == true)
		{
			cnt += 1;
			continue;
		}
		if (ad[st[i]] == false)
		{
			ad[st[i]] = true;
			cnt += 2;
		}
	}
	cout << cnt << endl;
}
 
signed main()
{
	IOS;
	int tt = 1; cin >> tt;
	while (tt--) solve();
	return 0;
}

C. Cypher

题意

给你一个N位数的锁(0-9),告诉你经过一些操作后现在的状态

之后给你每一位是怎么操作的:U 和 D 分别代表向上移动和向下移动。

要你找到操作前的锁的状态

思路

反之而行 U代表要向下找 D代表要向上找

分别统计出现个数 并对10取余

最后是cntD - cntU + 那一位现在的状态

超过9和比0小都要 -10 / +10

把每一位放到vector存一下最后输出

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
int n, m, cnt;
int a[N];
int ad[300];
void solve()
{
	vector<int> ve;
	int n; cin >> n;
	for (int i = 1; i <= n; i++) cin >> ad[i];
	for (int i = 1; i <= n; i++)
	{
		int si = 0; cin >> si;
		string st; cin >> st;
		int cntd = 0, cntu = 0;
		for (int i = 0; i < si; i++)
		{
			if (st[i] == 'U') cntu += 1; // 向上
			else cntd += 1; // d 向下
		}
		cntd %= 10, cntu %= 10;
		int tmp = cntd - cntu;
		int res = ad[i] + tmp;
		if (res > 9) ve.push_back(res - 10);
		else if (res < 0) ve.push_back(res + 10);
		else ve.push_back(res);
	}
	for (auto it : ve) cout << it << ' ';
	puts("");
}
 
signed main()
{
	IOS;
	int tt = 1; cin >> tt;
	while (tt--) solve();
	return 0;
}

D. Double Strings

题意

给你 n (1e5)个字符串 它们的长度 <= 8 

你需要知道 第 i 个字符串是不是由 除 第 i 个字符串外 任意两个字符串组成的

可以是两个一样的字符串组成

如果可以找到,那么第 i 个字符串就需要你输出 1 找不到输出 0

思路

用map<string,bool> mp存一下对应字符串是否出现过

后面只需要对每一个字符串遍历能不能找得到两个子串即可

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m, cnt;
int a[N];
int ad[300];
string st[N];
 
void solve()
{
	map<string, bool> mp;
	int n; cin >> n;
	for (int i = 1; i <= n; i++) cin >> st[i], mp[st[i]] = true;
	for (int i = 1; i <= n; i++)
	{
		bool flag = false;
		int len = st[i].size();
		for (int j = 1; j < len; j++)
		{
			string s1 = "", s2 = "";
			for (int k = 0; k < j; k++) s1 += st[i][k];
			for (int k = j; k < len; k++) s2 += st[i][k];
			if (mp[s1] && mp[s2])
			{
				flag = true;
			}
		}
		if (flag) cout << 1;
		else cout << 0;
	}
	cout << '\n';
}
 
signed main()
{
	IOS;
	int tt = 1; cin >> tt;
	while (tt--) solve();
	return 0;
}

E. Mirror Grid

题意

首先给你一个正方形矩阵的边长

之后把这个01矩阵告诉你

它想要把这个矩阵翻转90°,180°,270° 并且原来什么样翻转完还想要什么样

为了达到这个效果 它研究出的魔法是 可以让这个01矩阵的任意位置 0->1 或 1->0

现在想要知道施展多少次这个魔法能保证翻转这些角度矩阵仍不变

思路

找到表达式即可

maze[i][j] —> maze[j][n - i + 1] —> maze[n - i + 1][n - j + 1] —> maze[n - j + 1][i]

只要统计这四个的位置1多还是0多 对小的那一方施展魔术加到cnt里面就行

需要打个bool st[i][j] 表示那四个位置都用过了

对了这个01矩阵我当成int maze[i][j]调试了半天没找到错

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 110;
const int INF = 0x3f3f3f3f;
//int dx[4] = { 1,0,-1,0 }, dy[4] = {0,1,0,-1};
int n, m, cnt;
char maze[N][N];
bool st[N][N];
void solve()
{
	cin >> n;
	m = 4, cnt = 0;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			cin >> maze[i][j];
	if (n % 2 == 1) st[(n + 1) / 2][(n + 1) / 2] = true;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			if (st[i][j]) continue;
			int cnt1 = 0;
			if (maze[i][j] == '1') cnt1 ++;
			if (maze[j][n - i + 1] == '1') cnt1 ++;
			if (maze[n - i + 1][n - j + 1] == '1') cnt1 ++;
			if (maze[n - j + 1][i] == '1') cnt1 ++;
			st[i][j] = st[j][n - i + 1] = st[n - i + 1][n - j + 1] = st[n - j + 1][i] = true;
			if (cnt1 < m - cnt1) cnt += cnt1;
			else cnt += (m - cnt1);
		}
	}
	cout << cnt << '\n';
}
 
signed main()
{
	IOS;
	int tt = 1; cin >> tt;
	while (tt--)
	{
		memset(st, false, sizeof st);
		solve();
	}
	return 0;
}

F. Yet Another Problem About Pairs Satisfying an Inequality

题意

给你一个数组 a_1,a_2,a_3,...,a_n。请数出有多少对索引 1 \leqslant i,j \leqslant n 使得 a_i < i < a_j < j

思路

化简 只需要找到一些下标满足 a_i < i 即可

也就是 现在要从那些可行的下标中找到符合 i < a_j的几组下标

庆幸的是如果对一个i而言如果 i < a_j 那么之前符合条件的所有 i都满足

重点来了——

那么对于一个a_j而言,如果满足了 a_j > i 那就说明之前所有的i都满足

所以我们只需要遍历所有可行下标的 a_j 然后找到第一个符合 a_j > i 的下标

也就是说 在存 一群符合题意的 i 的vector<int> ba中找到第一个大于等于a_j的 下标idx

也就是lower_bound()这样一个二分搜索的方法 之前老以为是O(n)

res += idx 即可

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
//typedef pair<char, int> PCI;
//const int N = 110;
const int INF = 0x3f3f3f3f;
//const int N = 1010;
//int dx[4] = { 1,0,-1,0 }, dy[4] = {0,1,0,-1};
const int N = 2e5 + 10;
int n, m, cnt;
int a[N];
int sum[N];
 
void solve()
{
	vector<int> ve;
	vector<int> ba;
	int n; cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		if (i > a[i]) ve.push_back(i);
	}
	int length = ve.size();
	int res = 0;
	for (int i = 0;i < length;i ++)
	{
		res += lower_bound(ba.begin(), ba.end(), a[ve[i]]) - ba.begin();
		ba.push_back(ve[i]);
	}
	cout << res << endl;
}
 
signed main()
{
	//IOS;
	int tt = 1; cin >> tt;
	while (tt--) solve();
	return 0;
}

G. Good Key, Bad Key

题意

开始题看错了根本没看懂样例
你有 n个箱子。第 i 个箱子中有 ai 个硬币。你需要按照从箱子 1 号到箱子 n 号的顺序打开所有箱子。

你可以用以下两种钥匙之一打开一个箱子:
- 好钥匙:使用一次消耗 k 个硬币。
- 坏钥匙:使用时不消耗硬币,但会使所有未打开的箱子中的硬币数减半(包括正要打开的这个箱子)。

所有钥匙用过一次就会断掉(别想着买一把好钥匙开完所有箱子了),好钥匙需要重复付费,坏钥匙效果会重复计算(也就是说这个箱子价值/2,后一个箱子到它的时候价值要/4)。

思路

贪心 

如果可以的话全用好钥匙,如果收益不好就先用好钥匙 后面不好的再用坏钥匙

朝着这个思路找到收益最大值 fx 如果后面坏钥匙太多了 fx / (1ll << cnt) == 0后面就没收益了

也就是说枚举要用 i 个好钥匙 用 j 枚举后面的箱子 一直加 (a[j] / (1ll << (j - i))) 直到 fx = 0

最后别忘了 res -= k * i 

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
//typedef pair<char, int> PCI;
//const int N = 110;
const int INF = 0x3f3f3f3f;
//const int N = 1010;
//int dx[4] = { 1,0,-1,0 }, dy[4] = {0,1,0,-1};
const int N = 2e5 + 10;
int n, m, cnt;
int a[N];
int sum[N];
int res[N];
void solve()
{
	int n, k; cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		sum[i] = sum[i - 1] + a[i];
	}
	int fw = *max_element(a + 1, a + 1 + n);
	int maxid = sum[n] - n * k;
	for (int i = 0; i <= n; i++)
	{
		int res = sum[i];
		for (int j = i + 1; j <= n; j++)
		{
			res += (a[j] / (1ll << (j - i)));
			if (fw / (1ll << (j - i)) == 0) break;
		}
		res -= i * k;
		maxid = max(maxid, res);
	}
	cout << maxid << endl;
}
 
signed main()
{
	//IOS;
	int tt = 1; cin >> tt;
	while (tt--) solve();
	return 0;
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值