【AcWing】第 64 场周赛 【2022.08.13】

竞赛网址:https://www.acwing.com/activity/content/competition/problem_list/2157/

A. A + B

题目描述

输入两个整数,求这两个整数的和是多少。

输入格式

输入两个整数A, B,用空格隔开

输出格式

输出一个整数,表示这两个数的和

数据范围

0 ≤ A, B ≤ 10 ^ 8

样例输入:

3 4

样例输出:

7

C++ 代码

#include <iostream>

using namespace std;

int main()
{
    int a , b;
    cin >> a >> b;
    cout << a+b << endl;
    return 0;
}

B. 三国语言

题目描述

已知,菲律宾人在说话时,一定会在最后加上 po,日本人在说话时,一定会在最后加上 desumasu,韩国人在说话时,一定会在最后加上 mnida

现在,有 n 个外国人,每个人都来自菲律宾或日本或韩国,他们每个人都说了一句话,请你根据他们说的话来判断他们具体是哪国人。

输入格式

第一行包含整数 n,表示外国人的数量。

接下来 n 行,每行包含一个字符串,表示其中一人说的一句话。

输入保证字符串中只包含小写字母和下划线,并且一定以上述四个后缀之一结尾。

输出格式

n 行,第 i 行输出第 i 个外国人是哪国人。

菲律宾人表示为 FILIPINO,日本人表示为 JAPANESE,韩国人表示为 KOREAN

数据范围

前三个测试点满足 1 ≤ n ≤ 10
所有测试点满足 1 ≤ n ≤ 30,每个输入字符串长度范围 [1,1000]

输入样例:

    8
    kamusta_po
    genki_desu
    ohayou_gozaimasu
    annyeong_hashimnida
    hajime_no_ippo
    bensamu_no_sentou_houhou_ga_okama_kenpo
    ang_halaman_doon_ay_sarisari_singkamasu
    si_roy_mustang_ay_namamasu

输出样例:

    FILIPINO
    JAPANESE
    JAPANESE
    KOREAN
    FILIPINO
    FILIPINO
    JAPANESE
    JAPANESE

思路

通过观察可以发现,只需要判断每串字符串的最后一个字母,就可以判断是哪国人说的。

C++ 代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

void solve()
{
	string s;
	getline(cin,s);
	
	int len = s.size() - 1;
	switch(s[len])
	{
		case 'o':{
			puts("FILIPINO");
			break;
		}
		case 'u':{
			puts("JAPANESE");
			break;
		}
		case 'a':{
			puts("KOREAN");
			break;
		}
	}
	
	return ;
}

int main()
{
	int T;
	cin >> T;
	
	T ++;
	
	while(T --)
		solve();
	
	return 0;
}

C. 子数组异或和【补】

题目描述

给定一个长度为 n 的整数数组 a\_1,a\_2,…,a\_n

请你统计一共有多少个数组 a非空连续子数组能够同时满足以下所有条件:

  • 该连续子数组的长度为偶数。
  • 该连续子数组的前一半元素的异或和等于其后一半元素的异或和。

例如,当给定数组为 \[1,2,3,4,5\] 时,满足条件的连续子数组只有 1 个:\[2,3,4,5\]

输入格式

第一行包含整数 n

第二行包含 n 个整数 a\_1,a\_2,…,a\_n

输出格式

一个整数,表示满足条件的连续子数组的数量。

数据范围

前三个测试点满足 2 ≤ n ≤ 10
所有测试点满足 2 ≤ n ≤ 3 * 10^50 ≤ a[i] < 2 ^ 20

输入样例1:

5
1 2 3 4 5

输出样例1:

1

输入样例2:

6
3 2 2 3 7 6

输出样例2:

3

输入样例3:

3
42 4 2

输出样例3:

0

思路

冷知识:^(异或):不进位加法

1.先预处理一下前缀和 s
image

  • 前半部分的异或和:s[i-m] ^ s[i-2m]
  • 后半部分的异或和:s[i] ^ s[i-m]
  • s[i-m] ^ s[i-2m] = s[i] ^ s[i-m]
  • 左右互换一下(就类似于加法)
  • s[i-m] ^ s[i-m] = s[i] ^ s[i-2m]
  • 冷知识:两个相同的数进行异或,为0
  • 则:s[i] ^ s[i-2m] = 0
  • 即:s[i] = s[i-2m]

2.判断从0到i-1中有多少个j满足以下两个条件

  • s[i] = s[j]
  • i - j是偶数 , 即 i - j % 2 == 0

3.利用哈希表进行优化

  • 哈希表可以实现O(1)时间的增、删、改

C++ 代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <unordered_map>

using namespace std;

typedef long long ll;

const int N = 300010;

int n;
int a[N];

int main()
{
	cin >> n;
	for(int i = 1;i <= n;i ++)
		cin >> a[i];
	
	ll ans = 0, sum = 0;
	unordered_map<int,int> s[2];//有两个哈希表,s[1]用来存储奇数的,s[0]用来存储偶数的
	
	s[0][sum] ++;//预处理第一项
	
	for(int i = 1;i <= n;i ++)
	{
		sum ^= a[i];
		ans += s[i%2][sum];
		s[i%2][sum] ++;
	 } 
	
	
	cout << ans << endl;
	
	return 0;
}
posted @ 2022-08-15 09:56  HeyStar  阅读(73)  评论(0)    收藏  举报