Codeforces Round 928(div.4)题解

A Vlad and the Best of Five

题目描述:
有t个长度为5的字符串,看是A多还是B多,A多输出A,B多输出B 

输入描述:
第一行是整型t(1≤t≤32),之后t行为长长度为5的字符串

示例:
输入
8
ABABB
ABABA
BBBAB
AAAAA
BBBBB
BABAA
AAAAB
BAAAA
输出:
B
A
B
A
B
A
A
A

AC代码:

#include <bits/stdc++.h>
 
using namespace std;
char a[6];
int b[2];
int main()
{
	int t;
	cin >> t;
	for (int i = 0; i < t; i++)
	{
		memset(b, 0, sizeof(b));
		scanf("%s", a);
		for (int k = 0; k < 5; k++)
		{
			if (a[k] == 'A')
				b[0]++;
			else
				b[1]++;
		}
		if (b[0] > b[1])
			cout << "A" << endl;
		else
			cout << "B" << endl;
 
	}
	return 0;
}

B Vlad and Shapes

题目描述:
有n×n个方格,有一个正方形或三角形放置在其中(用1表示),其中三角形的第i行1的个数为2×i+1,可以倒置,但不可旋转90°。判断由1组成的图案是正方形还是三角形。

示例:
输入:
6
3
000
011
011
4
0000
0000
0100
1110
2
11
11
5
00111
00010
00000
00000
00000
10
0000000000
0000000000
0000000000
0000000000
0000000000
1111111110
0111111100
0011111000
0001110000
0000100000
3
111
111
111
输出:
SQUARE
TRIANGLE
SQUARE
TRIANGLE
TRIANGLE
SQUARE

分析:
个人认为是考察枚举,但不用把所有为1的部分都枚举出,判断三角形的方法是 从(0,0)开始搜索遇到的第一个1,看其右边和下方有没有1,若右边有1下方无1(倒置)或右边无1下方有1则为三角形,其余为正方形。

AC代码:

#define  _CRT_SECURE_NO_WARNINGS
 
#include <bits/stdc++.h>
using namespace std;
int a[20][20];
int main()
{
	int t;
	cin >> t;
	for (int i = 0; i < t; i++)
	{
		int n;
		cin >> n;
		int k, j;
		for (k = 0; k < n; k++)
			for(j=0;j<n;j++)
				scanf("%1d", &a[k][j]);
		int flag = 0;
		for (k = 0; k < n; k++)
		{
			for (j = 0; j < n; j++)
			{
				if (a[k][j] == 1&&a[k][j+1]==1)
					if (a[k + 1][j] == 1)
					{
						cout << "SQUARE" << endl;
						flag = 1;
						break;
					}
					else
					{
						cout << "TRIANGLE" << endl;
						flag = 1;
						break;
					}
				else if (a[k][j] == 1 && a[k][j + 1] == 0)
				{
					cout << "TRIANGLE" << endl;
					flag = 1;
					break;
				}
			}
			if (flag)
				break;
		}
	}
	return 0;
}

C Vlad and a Sum of Sum of Digits

题目描述:
1到n的整数,将每个整数替换成其数位之和再相加,给出相加的结果。例如1到12,则数字之和为1+2+3+4+5+6+7+8+9+1+2+3=51 (时间限制0.5s)

输入描述:
测试数据共t个(1≤t≤10e4),测试数据大小范围为1到2×10e5

输出描述:
相加结果

示例:
输入:
7
12
1
2
3
1434
2024
200000
输出:
51
1
3
6
18465
28170
4600002

分析:
因为实现限制,故肯定不能二重循环,最多一次循环,即不能输入一个数字处理一个数字,所以考虑在最之前就把所有数据处理好,发现1到n相加之和=1到 n-1相加之和+第n个数字的数位之和,易得正确答案。

AC代码:

#include <bits/stdc++.h>
 
using namespace std;
int a[200010];
int main()
{
	a[1] = 1;
	for (int i = 2; i <= 200000; i++)
	{
		a[i] = a[i - 1];
		int b = i;
		while (b)
		{
			a[i] += b % 10;
			b /= 10;
		}
	}
	int t;
	cin >> t;
	for (int i = 0; i < t; i++)
	{
		int n;
		cin >> n;
		cout << a[n]<<endl;
	}
	return 0;
}

备注:
写题是完全没想到能先把所有数据处理了,也没想到如何循环处理所有数据!!TLE到崩溃(QAQ)

D Vlad and  Division

题目描述:
有一堆数,若两个数从1到31位(2进制)是否都相反,则可放到一组,看这一堆数一共能分成多少组。

输入描述:
第一行为t组测试数据
每个测试数据的第一行输入n,代表一共n个数,n从1到2×10e5
第二行输入n个数,测试数据范围从1到2的31次方

输出描述:
一个数字,表示能分成多少组

示例:
输入:
9
4
1 4 3 4
2
0 2147483647
5
476319172 261956880 2136179468 1671164475 1885526767
3
1335890506 811593141 1128223362
4
688873446 627404104 1520079543 1458610201
4
61545621 2085938026 1269342732 1430258575
4
0 0 2147483647 2147483647
3
0 0 2147483647
8
1858058912 289424735 1858058912 2024818580 1858058912 289424735 122665067 289424735
输出:
4
1
3
2
2
3
2
2
4

分析:
考察点为map,用map记录是否有相匹配的数,具体操作为遍历输入的数a,看map中是否有与该数相匹配的数(这里的匹配指的是从1到31位都异或),即map中是否有c^a,其中c=2147483647,若有,则map中c^a的个数减1,组数加1;若没有,则map中a的个数加1.其中要注意的是一组中最多只有2个数

AC代码:

#include <bits/stdc++.h>
using namespace std;
int a[200010];
signed main()
{
	int t;
	int c = 2147483647;
	cin >> t;
	for (int i = 0; i < t; i++)
	{
		int n;
		cin >> n;
		int ans = 0;
		map<long long, int>mp;
		for (int k = 0; k < n; k++)
		{
			cin >> a[k];
		}
		for (int k = 0; k < n; k++)
		{
			if (mp[a[k]^c])
			{
				mp[a[k]^c]--;
				ans++;
			}
			else
			{
				mp[a[k]]++;
			}
		}
		for (auto& it : mp)
			ans += it.second;
		cout << ans<<endl;
	}
	return 0;
}

备注:
一开始交上去WA了,百思不得其解,才发现是没考虑到一个组里只能塞两个数据(样例居然也能过......),后面补题发现问题,用了三层循环(先遍历数字,然后遍历数字后面的,看看有没有相匹配的数字(我是正选,即看a^b?=2147483647),没想到用map优化),TLE了

E Vlad and an Odd Ordering

题目描述:
有1到n的n张牌,把这些牌按照以下方式重新排列:
· 首先,把所有奇数牌从小到大排列
· 接着,放从小到大是奇数两倍的牌(即2乘以一个奇数)
· 接着,放从小到大是奇数三倍的牌(一点用都没有!!!!!!)
· 接着,放从小到大是奇数四倍的牌
· 以此类推,直到排完所有的牌为止。
求排完序后的第k张牌是什么?

输入描述:
第一行为t组测试数据
每个测试数据由两个整型n和k组成,n表示有n张牌,k表示第k张牌。

输出描述:
一个整型表示第k张牌

示例:
输入:
11
7 1
7 2
7 3
7 4
7 5
7 6
7 7
1 1
34 14
84 19
1000000000 1000000000
输出:
1
3
5
7
2
6
4
1
27
37
536870912

分析:
方法一:
可以尝试找找规律
e.g n=18时
第一次排 1 3 5 7 9 11 13 15 17(2t+1,t从0开始)
第二次排 2 6 10 14 18(4t+2,t从0开始)
第三次排 4 12(8t+2,t从0开始)
第四次排 8(16t+8,t从0开始)
第五次排 16(32t+16,t从0开始)
故找到规律,只用看k在哪一个区间范围之内即可,mt+m/2≤n,即t≤(2n-m)/(2*i)(不大于其的整数),所以循环m即可,m每进行一轮循环乘2,最后看k是那一轮的然后带入公式mt+m/2即可

AC代码:

#include <bits/stdc++.h>
using namespace std;
signed main()
{
	int t;
	cin >> t;
	for (int i = 0; i < t; i++)
	{
		int n, k;
		cin >> n >> k;
		int m,t;
		for (m = 2;; m *= 2)
		{
			t = k;
			k = k - (int)(ceil)(2 * n - m) / (2 * m)-1;
			if (k <= 0)
				break;
		}
		cout << m * (t - 1) + m / 2<<endl;
	}
	return 0;
}

方法二:
分治的思想
第一次是从f([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18])中选
第二次是从f([2,4,6,8,10,12,14,16,18])中选
        而第二次可化为f([1,2,3,4,5,6,7,8,9])*2中选
第三次是从f([4,8,12,16])中选
        即f([1,2,3,4])*4中选
第四次是从f([1,2])*8中选
第五次是从f([1])*16中选
而每次选都是只能选择奇数,则每一次共有(j+1)/2个选择,其中j为每一次的数组个数,而一次变换j=j/2,故循环即可。

AC代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long 
signed main()
{
	int t;
	cin >> t;
	for (int i = 0; i < t; i++)
	{
		int n, k;
		cin >> n >> k;
		int m = 1;
		int k1;
		for (int j = n;k>(j+1)/2; j /= 2)
		{
			k = k - (j+1)/2;
			m = m * 2;
		}
		cout << (2*k-1) * m<<endl;
	}
	return 0;
}

最后:F和G题现在还不会,等学完算法入门再回来补,留个坑

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值