集训周记 第二周

编程学习笔记:

我在语雀里面格式是对的,但导到 CSDN 里面有些地方就乱了,私密马赛
(本来应该上周发的,周末出去玩了就忘记了…)

1.H - 中位数

Description

给定一个长度为 𝑁_N_ 的非负整数序列 𝐴_A_,对于前奇数项求中位数。

Input

第一行一个正整数 𝑁_N_。
第二行 𝑁_N_ 个正整数 𝐴1…𝑁_A_1…N

Output

共 ⌊𝑁+12⌋⌊2_N_+1⌋ 行,第 𝑖_i_ 行为 𝐴1…2𝑖−1_A_1…2_i_−1 的中位数。

Sample 1

InputcopyOutputcopy
```
7
1 3 5 7 9 11 6
 | ```
1
3
5
6

|

Sample 2

InputcopyOutputcopy
```
7
3 1 5 9 8 7 6
 | ```
3
3
5
6

|

Hint

对于 20%20% 的数据,𝑁≤100_N_≤100;
对于 40%40% 的数据,𝑁≤3000_N_≤3000;
对于 100%100% 的数据,1≤𝑁≤1000001≤_N_≤100000,0≤𝐴𝑖≤1090≤_Ai_≤109。

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>

using namespace std;

#define llu long long


int main() {
	priority_queue<int> p;//大头
	priority_queue<int, vector<int>, greater<int>> q;//小头
	int N; scanf("%d", &N);
	if (N == 1) {
		int x; scanf("%d", &x);
		printf("%d\n", x); return 0;
	}
	int x1, x2;
	scanf("%d %d", &x1, &x2);
	if (x1 <= x2) {
		p.push(x1); q.push(x2);
	}
	else {
		p.push(x2); q.push(x1);
	}
	printf("%d\n", x1);
	for (int i = 3; i <= N; i++) {
		int tmp; scanf("%d", &tmp);
		if (i % 2 == 1) {//奇数
			if (tmp > p.top()) {
				q.push(tmp);
			}
			else {
				p.push(tmp);
			}
			while (fabs(q.size() - p.size()) != 1) {
				if (p.size() > q.size()) {
					q.push(p.top());
					p.pop();
				}
				else {
					p.push(q.top());
					q.pop();
				}
			}
			if (q.size() > p.size()) {
				printf("%d\n", q.top());
			}
			else {
				printf("%d\n", p.top());
			}
		}
		else {//偶数
			if (tmp > p.top()) {
				q.push(tmp);
			}
			else {
				p.push(tmp);
			}
		}
	}
	return 0;
}

收获:
通过这道题,深度了解了 queue 的大头堆 与小头堆(居然还能这么用)
这道题目把所有的数据分成了两个堆,在逐步将所输入的数据的过程中,将
所有的数据分成了两个堆 [大头堆]小->大(出口) 中位数?(出口)小 ->大[小头堆]

2.F-Cities and States S

Description

Farmer John 有若干头奶牛。为了训练奶牛们的智力,Farmer John 在谷仓的墙上放了一张美国地图。地图上表明了每个城市及其所在州的代码(前两位大写字母)。
由于奶牛在谷仓里花了很多时间看这张地图,他们开始注意到一些奇怪的关系。例如,FLINT 的前两个字母就是 MIAMI 所在的 FL 州,MIAMI 的前两个字母则是 FLINT 所在的 MI 州。
确切地说,对于两个城市,它们的前两个字母互为对方所在州的名称。
我们称两个城市是一个一对「特殊」的城市,如果他们具有上面的特性,并且来自不同的州。对于总共 𝑁_N_ 座城市,奶牛想知道有多少对「特殊」的城市存在。请帮助他们解决这个有趣的地理难题!

Input

输入共 𝑁+1_N_+1 行。
第一行一个正整数 𝑁_N_,表示地图上的城市的个数。
接下来 𝑁_N_ 行,每行两个字符串,分别表示一个城市的名称(2∼102∼10 个大写字母)和所在州的代码(22 个大写字母)。同一个州内不会有两个同名的城市。

Output

输出共一行一个整数,代表特殊的城市对数。

Sample 1

InputcopyOutputcopy
```
6
MIAMI FL
DALLAS TX
FLINT MI
CLEMSON SC
BOSTON MA
ORLANDO FL
1

Hint

数据规模与约定

对于 100%100% 的数据,1≤𝑁≤2×1051≤_N_≤2×105,城市名称长度不超过 1010。

【超时方案】

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>
using namespace std;

//【substr】
/*
在 C++ 中,std::string 类的 substr 成员函数用于从字符串中提取子字符串。这个函数返回一个新的字符串对象,
该对象包含原始字符串中从指定位置开始到指定长度(或字符串末尾,如果指定的长度超出了剩余部分的长度)的子串。

[原型]
要被处理的字符串.substr(size_type pos = 0, size_type len = npos) const;
//                    起始位置              要提取的字符数
*/

int main() {
	int N; scanf("%d", &N);
	map<string, string> s_main;        // 城市    州
	map<string, string> s_firstname;   // 城市    前名
	for (int i = 0; i < N; i++) {
		string tmp_city, tmp_state; cin >> tmp_city >> tmp_state;
		s_main[tmp_city] = tmp_state;
		//s_firstname[tmp_city] = tmp_city.substr(0, 2);
	}

	int cnt = 0;//找一个删一个
	for (auto pair1 : s_main) {
		string state = pair1.second;
		string firstname = pair1.first.substr(0, 2);
		for (auto pair2 : s_main) {
			string state2 = pair2.second;
			string firstname2 = pair2.first.substr(0, 2);
			if (state == firstname2 && firstname == state2) {
				cnt++;
			}
		}
		//s_main.erase(pair1.first);
	}
	cout << cnt/2 << endl;
	return 0;
}

【运行成功】

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>
using namespace std;
#define ll long long


ll v[1010][1010] = { 0 };
int main() {
	ll n; cin >> n;
	ll ans = 0;

	for (int i = 1; i <= n; i++) {
		string a, b; cin >> a >> b;
		int ta = (a[0] - 'A') * 26 + a[1] - 'A';
		int tb = (b[0] - 'A') * 26 + b[1] - 'A';
		ans += v[tb][ta];
		
		
		if (ta == tb) {
			ans -= v[ta][tb];
		}
		v[ta][tb]++;
	}
	printf("%lld", ans);

	return 0;
}

收获:
学长NB。我原本看到两个元素都是字符串,然后想想今天学了map,就直接一眼丁真想用map,但是对 map 的遍历又不是太熟(有重复的操作过程),还是学长NB,没那么多花里胡哨的,直接一次循环解决问题。

3.D-单词数

lily的好朋友xiaoou333最近很空,他想了一件没有什么意义的事情,就是统计一篇文章里不同单词的总数。下面你的任务是帮助xiaoou333解决这个问题。

Input

有多组数据,每组一行,每组就是一篇小文章。每篇小文章都是由小写字母和空格组成,没有标点符号,遇到#时表示输入结束。

Output

每组只输出一个整数,其单独成行,该整数代表一篇文章里不同单词的总数。

Sample

InputcopyOutputcopy
```
you are my friend

【istringstream知识补充】

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>
using namespace std;

//【关于 换行】
//在 C++ 中 最好用 \n 而不是 endl .因为后者会影响缓冲区,比较慢

//【关于 cin 和 cout】
//使用 ios::sync_with_stdio(0);cin.tie(0);  //关闭同步流
/*Q:cout 默认保留小数点后6位,但如果我们想只保留 4 位该怎么办?
  A: eg. cout << x << setprecision(4);             */ //setprecision —— 设置精度

//【字符串分割 istreamstring  getline】
vector<string> splitString(const string str, char delimiter) {
    vector<string> tokens;//分割完毕的字符串
    istringstream tokenStream(str);//这是一个输入字符串流,它使用str作为其内容。
    //通过使用 getline,我们可以从这个流中按行(在这个上下文中,“行”是由分隔符定义的字符串块)读取数据。
    string token;
    while (getline(tokenStream, token, delimiter)) {
        tokens.push_back(token);
    }
    return tokens;
}//将分割完的字符串存入 vector<string> 后一起返回

// istreamstring    istringstream 类允许你从字符串中读取数据,就像从文件或标准输入中读取一样。
                  //这使得它非常适合于字符串分割、解析等任务。

int main() {
	//【切割字符串】—— 使用 istringstream和 getline
    string str = "one,two,three,four";
    auto tokens = splitString(str, ',');
    for (const auto& token : tokens) {
        cout << token << '\n';
    }
	return 0;
}


【本题答案】

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>
using namespace std;

set<string> splitMine(const string str,char del);

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	string tmp;
	while (getline(cin,tmp) && tmp != "#") {
		if (tmp == " ") {
			printf("%d\n", 0); continue;
		}
		auto tokens = splitMine(tmp, ' ');
		printf("%d\n", tokens.size());
	}
	return 0;
}

set<string> splitMine(const string str, char del) {
	set<string> tokens;
	istringstream tokenStream(str);
	string out;
	while(getline(tokenStream, out, del)) {
		tokens.insert(out);
	}
	return tokens;
}

收获:
学会了进行字符串的分割(不是简单的使用 substr),
而是使用了 istringstream + getline
getline(输入的istringstream类,输出存储处,需要读到的del)
(详细的可以见上面那段代码里的 splitMine 函数)

4.queue

【基础知识】

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>
using namespace std;

//队列 queue

int main(){
	queue<int> s;
	int n = 0; scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		int tmp; scanf("%d", &tmp);
		s.push(tmp);
	}
	while (!s.empty()) {
		int tmp = s.front(); printf("%d ", tmp);
		s.pop();
	}
	return 0;
}

/*
queue的有关操作
q.front()返回队首元素
q.back()返回队尾元素
q.push()在队尾插入元素
q.pop()弹出队首元素
q.empty()队列是否为空
q.size()返回队列中元素的数量
*/

【样例——约瑟夫环】

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>
using namespace std;

//p1996 约瑟夫环

int main() {
	int n,m; scanf("%d %d", &n,&m);
	queue<int> q;
	for (int i = 1; i <= n; i++) {
		q.push(i);
	}
	int tmp = 0;
	while (!q.empty()) {
		tmp++;
		if (tmp % m != 0) { 
			q.push(q.front());
			q.pop();
		}
		else {
			printf("%d ", q.front());
			q.pop();
		}
	}
	return 0;
}

5.set 和 map

【set】

#define _CRT_SECURE_NO_WARNINGS 1

//【set】

#include<bits/stdc++.h>
using namespace std;

int main() {
	set<int> s;                   //从小到大,升序排列
	// set<int,greater<int> > s;  //从大到小,降序排列
	for (int i = 0; i < 5; i++) {
		int tmp; cin >> tmp;
		s.insert(tmp);
	}
	for (auto x : s) {
		cout << x << " ";
	}
	return 0;
}

/*
【set 集合】
set是一个容器 以红黑树的数据结构来实现
set中的元素按照一定的顺序进行存储与访问,而且每个元素-只会在sét里出现一次- -其中元素默认是按照升序进行排序的-,但也可以通过自定义比较函数来实现其他的排序方式
我们不用理解set的实现原理 只用把set当作数学上的一个集合就行 时间复杂度O(logn)
set一般有什么用 [去重 排序]

st.insert(x)当set里没有等价元素时,将x插入到set里                         (set里的插入不是push,是insert)
st.erase(x)从set中删除指定元素                                          (set里的删除不是pop ,是 erase)
st.clear()清空set容器
st.count(x)返回set内x元素的数量 因为最多存在一个 所以返回值要么1要么0
st.empty(判断set是否为空
st.size()返回set内元素的个数
*/

//【multiset】

【map】

#define _CRT_SECURE_NO_WARNINGS 1

//【map】

/*
[map]
std::map默认按照键的升序进行排序。这是通过std::less<Key>仿函数来实现的,该仿函数内部主要调用元素的<运算符来进行比较。
(是用 key ! 进行排序的!,别搞错了)

[set]
根据存储值进行排列

*/


#include<bits/stdc++.h>
using namespace std;

int main() {
	//-【创建 map】-----
	map<int, string> myMap; // 创建一个空的 map,键类型为 int,值类型为 string  
	//  key  value

	// 使用初始化了 myMap2 其中有三个键值对    map中默认升序排列 
	map<int, string> myMap2 = {
		{1, "two"},
		{2, "one"},
		{3, "three"}
	};


	//-【插入元素】-----
	 方法1:使用下标操作符 (一般用这个,不用 insert,主要是没有必要)
	//myMap[1] = "one"; // 使用下标操作符,如果键不存在则插入新元素  
	///*
	//这行代码尝试将键为1、值为"one"的键值对插入到myMap中。
	//如果myMap中不存在键为1的元素,则使用下标操作符会插入一个新的键值对。如果键已经存在,则更新该键对应的值。
	//*/
	//
	 或者 方法2:使用insert函数 
	//auto result = myMap.insert(make_pair(2, "two")); // 使用 insert 函数  或者 myMap.insert({2,"two"})
	//if (!result.second) {
	//	// 插入失败,通常是因为键已存在
	//	printf("使用insert方法插入失败\n");
	//}
	//else {
	//	printf("使用insert方法插入成功\n");
	//}
	///*
	//这行代码尝试使用insert成员函数向myMap中插入一个新的键值对,键为2,值为"two"。
	//insert函数返回一个pair<iterator, bool>类型的值,其中iterator指向新插入的元素(或已存在的元素,如果键已存在),
	//bool值表示插入是否成功(如果键已存在,则插入失败,返回false)。
	//*/


	//-【访问元素】-----
	方法1:使用下标操作符
	//string value = myMap[1]; // 访问键为 1 的元素的值  (危险!!!!!!!!!!)
	 注意:如果键不存在,则使用下标操作符会创建一个新元素,其值会被初始化为值类型的默认值  

	方法2:使用 find 成员函数更安全地访问
	 更安全的访问方式                               (安全!!!!!!!!!!)
	///*
	//用find成员函数。这种方法会尝试在map中查找指定的键,并返回一个指向找到的元素的迭代器。
	//如果未找到键,则返回map的end()迭代器。
	//*/
	//auto it = myMap.find(1);
	//if (it != myMap.end()) {//如果返回的是 end()迭代器,则说明没有,反之则说明有
	//	string value = it->second; // 访问找到的元素的值
	//	printf("通过find成员寻找到了:%s\n", value);
	//	//it->second 中的 second 是一个成员访问操作符,它用于访问迭代器 it 所指向的键值对中的“值”部分。
	//}


	//-【删除元素】-----
	//myMap.erase(1); // 删除键为 1 的元素  

	 或者使用迭代器  使用 find 成员
	//auto it = myMap.find(2);
	//if (it != myMap.end()) {
	//	myMap.erase(it);
	//}



	//-【遍历 map】-----
	for (const auto pair : myMap2) {
		cout << pair.first << ": " << pair.second << endl;
	}
	///*
	//由于pair是一个std::pair对象,您可以使用pair.first来访问键,使用pair.second来访问与键相关联的值。
	//因此,您的代码片段会遍历myMap2中的所有元素,并打印出每个元素的键和值。
	//*/

	 或者使用迭代器  (我喜欢用上面那个方法遍历)
	//for (auto it = myMap.begin(); it != myMap.end(); ++it) {
	//	cout << it->first << ": " << it->second << endl;
	//}
	
	return 0;
}

/*
【map】
C++ 中的 map 是一种关联容器,它存储的元素是键值对(key-value pairs)。
每个元素都有一个唯一的键(key)和与该键相关联的值(value)。
map 内部通常通过红黑树(Red-Black Tree)实现,这意味着 map 中的元素总是按照键的升序排列。
因此,map 提供了快速的查找、插入和删除操作,这些操作的时间复杂度通常为对数时间(O(log n)),其中 n 是 map 中元素的数量。

[注意事项]
map 中的键必须是唯一的。
map 中的元素按照键的升序排列。
访问不存在的键时,使用下标操作符会创建一个新元素。如果你只是想检查键是否存在,应该使用 find 成员函数。
map 的插入、删除和查找操作的时间复杂度通常为 O(log n)。

访问的时候使用 find成员!
或者 from 学长:
 for(auto x: mp){
	if(x.count() == 1){
		cnt++;
	}
 }
 //防止因为一直访问没有的东西一直开导致 TLE
*/

//[ map 中的 count ]   s.count(键);
/*
在 C++ 的 std::map 容器中,count 成员函数的行为与在其他一些容器(如 std::unordered_map 或 std::multiset)中略有不同。
在 std::map 中,由于键是唯一的,
因此 count 成员函数对于任何给定的键都会返回 0(如果键不存在于映射中)或 1(如果键存在于映射中)。
*/

/*
map.find(key);
map.erase(key);
map.insert();
map.count();
map.size();
map.clear();
map.empty();
*/

内容都写在注释里了,想运行相关内容的化自己解一下那块的注释就行了

6.string

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define int long long

//数组如果很大的话,需要定义在 main()函数 外面,否则会运行不了

//signed main() {
//	//【memset(数组名称,需要初始化的值,数组的每个元素的大小)】
//	int a[10];             //请注意:memset() 仅能的初始化值仅能为 0 或者 -1
//	memset(a, 0, sizeof(a));
//	for (auto x : a) {
//		cout << x << " ";
//	}
//	cout << endl;
//	memset(a, -1, sizeof(a));
//	for (auto x : a) {
//		cout << x << " ";
//	}
//	cout << endl;
//	return 0;
//}

/*
【string 类 常用函数】
length(); size(); 求长度
empty();          判断是否为空串
substr();         截取字符串
erase();          删除若干个字符
insert();         插入字符
replace();        替换字符
find();           寻找字符

还有,看下面
*/

signed main() {
	//字符串串联
	string s1 = "Hello";
	string s2 = "!";;
	cout << s1 + s2 << endl;
	//字符串的比较
	// getline()
	//字符串的长度
	cout << s1.length() << endl;

	//【string.erase(起始位,数几个)】;//有规律地指定删除
	s1.erase(1, 2);
	cout << s1 << endl;
	{
		/*1. 删除单个字符
             如果你想删除字符串中特定位置的字符,
			 你可以直接使用 erase 方法并传递该位置的索引(注意,索引从0开始)。*/
		string s = "Hello";
		size_t pos = s.find("H");  //在C++中,size_t 是一个无符号整数类型
		s.erase(pos,1);
		//cout << "#" << s << endl;b

		/*
		2. 删除一个范围内的字符
           你也可以指定一个范围(开始位置和长度),然后删除这个范围内的所有字符。
		*/
		s = "Hello";
		size_t start = 1;
		size_t length = 2;
		s.erase(start, length);
		//cout << "#" << s << endl;

		/*
		3. 删除满足条件的字符(使用算法)
           虽然 erase 方法本身不直接支持基于条件的删除,但你可以结合使用标准库中的算法
		   如 remove 或 remove_if)和 erase 来实现这一功能。
		*/
		s = "Hello";
		s.erase(remove(s.begin(), s.end(), 'o'), s.end());
		//cout << "#" << s << endl;
		/*
		在这个例子中,remove 函数并不直接修改原始字符串,
		而是将所有不匹配的字符(在这个例子中是除了 'o' 以外的所有字符)移动到字符串的开头,
		并返回一个指向新逻辑末尾的迭代器。然后,我们使用 erase 方法来删除从 remove 返回的迭代器
		到原始字符串末尾之间的所有字符,这些字符实际上就是所有 'o' 字符。
		*/
	}

	//【string.insert(要插入的位置,要插入的元素);】
	s1.insert(0, "1");
	cout << s1 << endl;

	//【string.replace(索引,要替换几个字符,替换上去的元素)】
	s1.replace(0, 1, "HaHa");
	cout << s1 << endl;

	//【find()】
	if (s1.find("666") == string::npos) {
		cout << "找不到" << endl;
	}
	else {
		cout << "找到了" << endl;
	}

	//【count(string.begin(),string.end(),'要找的字符')】

	string s = "Hello world";
	cout << count(s.begin(), s.end(), 'l') << endl;
	/*
	在 C++ 中,string::npos 是一个特殊的常量值,用于表示在字符串中未找到子字符串或字符时的位置。
	这个常量实际上是 std::string 类型所能表示的最大值,即 std::string::size_type 的最大值。
	由于字符串的索引是从 0 开始的,因此任何有效的索引值都小于 std::string::npos。
	*/

	//【string 转 int】【stoi()】
	/*
	string s3 = "123";
	string s4 = "6";
	cout << stoi(s3) + stoi(s4) << endl;*/

	//【int 转 string】【to_string】
	int a = 123, b = 456;
	string s5 = to_string(a) + to_string(b);
	cout << s5 << endl;
	return 0;
}

//int a[1001];

//signed main() {
//	int n, k; cin >> n >> k;
//	for (int i = 0; i < n; i++) {
//		a[i] = 1;
//	}
//	for (int i = 2; i <= k; i++) {
//		for (int j = 0; j < n; j++) {
//			if ((j + 1) % i == 0) {
//				a[j] = 0;
//			}
//		}
//	}
//	for (int i = 0; i < n; i++) {
//		if (a[i] == 1) {
//			cout << i + 1 << " ";
//		}
//	}
//	return 0;
//}


收获:
这个 string::npos 真的要注意一下,我们在 map.find()…的时候,如果找不到我们要找的键,便会返回 map.end()… 表示找不到,以防止你额外开空间(次数多了会爆)。
在字符串里面我们则是返回 string::npos , 而不是返回 flag 或者 true (别问为什么,我就这么错过😭,虽然不是在这道题错的,具体是哪道我倒是忘记了)

7.EOF

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define int long long

signed main() {
	string s;
	/*
	使用 EOF 的方式:
    在 C++ 中,EOF 是一个整数常量,通常用于表示文件结束。
	但是,getline 函数返回的是一个 std::istream 对象,
	该对象在读取失败或到达文件末尾时会转换为 false。
	因此,您不需要显式检查 s != EOF,因为 getline 已经为您处理了文件结束的情况。
	*/
	while (getline(cin, s)/*&& s != EOF*/) {

	}
	return 0;
}


8.B - Palindromes

A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string “ABCDEDCBA” is a palindrome because it is the same when the string is read from left to right as when the string is read from right to left. A mirrored string is a string for which when each of the elements of the string is changed to its reverse (if it has a reverse) and the string is read backwards the result is the same as the original string. For example, the string “3AIAE” is a mirrored string because ‘A’ and ‘I’ are their own reverses, and ‘3’ and ‘E’ are each others’ reverses. A mirrored palindrome is a string that meets the criteria of a regular palindrome and the criteria of a mirrored string. The string “ATOYOTA” is a mirrored palindrome because if the string is read backwards, the string is the same as the original and because if each of the characters is replaced by its reverse and the result is read backwards, the result is the same as the original string. Of course, ‘A’, ‘T’, ‘O’, and ‘Y’ are all their own reverses. A list of all valid characters and their reverses is as follows.

Character Reverse Character Reverse Character Reverse A A M M Y Y B N Z 5 C O O 1 1 D P 2 S E 3 Q 3 E F R 4 G S 2 5 Z H H T T 6 I I U U 7 J L V V 8 8 K W W 9 L J X X (镜像的概念)
Note that ‘0’ (zero) and ‘O’ (the letter) are considered the same character and therefore ONLY the letter ‘O’ is a valid character.

Input
Input consists of strings (one per line) each of which will consist of one to twenty valid characters. There will be no invalid characters in any of the strings. Your program should read to the end of file.

Output
For each input string, you should print the string starting in column 1 immediately followed by exactly one of the following strings.

STRING CRITERIA ‘ – is not a palindrome.’ if the string is not a palindrome and is not a mirrored string ‘ – is a regular palindrome.’ if the string is a palindrome and is not a mirrored string ‘ – is a mirrored string.’ if the string is not a palindrome and is a mirrored string ‘ – is a mirrored palindrome.’ if the string is a palindrome and is a mirrored string Note that the output line is to include the ‘-’s and spacing exactly as shown in the table above and demonstrated in the Sample Output below. In addition, after each output line, you must print an empty line.

Sample Input
NOTAPALINDROME
ISAPALINILAPASI
2A3MEAS
ATOYOTA

Sample Output
NOTAPALINDROME – is not a palindrome. ISAPALINILAPASI – is a regular palindrome.
2A3MEAS – is a mirrored string.
ATOYOTA – is a mirrored palindrome

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>

using namespace std;
//#define ll long long
//#define int long long

signed main() {
	string s;
	while (getline(cin, s)) {
		string s2 = s;
		reverse(s2.begin(), s2.end());
		//cout << s << endl << s2 << endl;
		int flag1 = 0, flag2 = 0;
		//回文数
		if (s == s2) {
			flag1 = 1;
		}
		//镜像
		if (flag1 == 0) {
			string s3 = s;
			for (auto& x : s3) {
				if (x == 'E') {
					x = '3';
				}
				else if (x == 'J') {
					x = 'L';
				}
				else if (x == 'S') {
					x = '2';
				}
				else if (x == 'Z') {
					x = '5';
				}
			}
			s2 = s3;
			reverse(s2.begin(), s2.end());
			if (s3 == s2) {
				cout << s << " -- " << "is a mirrored string." << endl << endl;
			}
			else {
				cout << s << " -- " << "is not a palindrome." << endl << endl;
			}
		}
		else {
			s2 = s;
			string s3 = s;
			for (auto& x : s3) {
				if (x == 'E') {
					x = '3';
				}
				else if (x == 'J') {
					x = 'L';
				}
				else if (x == 'S') {
					x = '2';
				}
				else if (x == 'Z') {
					x = '5';
				}
			}
			if (s3 == s2) {
				cout << s << " -- " << "is a mirrored palindrome." << endl << endl;
			}
			else {
				cout << s << " -- " << "is a regular palindrome." << endl << endl;
			}
		}
	}

	return 0;
}

不知道为什么会 wronganser 先把代码放这,以后强点了再回来看看

D - Shifts and Sorting

Let’s define a cyclic shift of some string ss as a transformation from s1s2…sn−1sns1s2…sn−1sn into sns1s2…sn−1sns1s2…sn−1. In other words, you take one last character snsn and place it before the first character while moving all other characters to the right.
You are given a binary string ss (a string consisting of only 0-s and/or 1-s).
In one operation, you can choose any substring slsl+1…srslsl+1…sr (1≤l<r≤|s|1≤l<r≤|s|) and cyclically shift it. The cost of such operation is equal to r−l+1r−l+1 (or the length of the chosen substring).
You can perform the given operation any number of times. What is the minimum total cost to make ss sorted in non-descending order?

Input

The first line contains a single integer tt (1≤t≤1041≤t≤104) — the number of test cases.
The first and only line of each test case contains a binary string ss (2≤|s|≤2⋅1052≤|s|≤2⋅105; si∈si∈ {0, 1}) — the string you need to sort.
Additional constraint on the input: the sum of lengths of strings over all test cases doesn’t exceed 2⋅1052⋅105.

Output

For each test case, print the single integer — the minimum total cost to make string sorted using operation above any number of times.

Examples

InputcopyOutputcopy
```
5
10
0000
11000
101011
01101001
 | ```
2
0
9
5
11

|

Note

In the first test case, you can choose the whole string and perform a cyclic shift: 10 →→ 01. The length of the substring is 22, so the cost is 22.
In the second test case, the string is already sorted, so you don’t need to perform any operations.
In the third test case, one of the optimal strategies is the next:

  1. choose substring [1,3][1,3]: 11000 →→ 01100;
  2. choose substring [2,4][2,4]: 01100 →→ 00110;
  3. choose substring [3,5][3,5]: 00110 →→ 00011.

The total cost is 3+3+3=93+3+3=9.

Sponsor

【正确代码】

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
	#define int long long
	int t; cin >> t; getchar();

	for (int i = 0; i < t; i++) {
		stack<char> s;
		char tmp;
		int num_0 = 0;
		int chenben = 0;

		while (~scanf("%c", &tmp) && tmp != '\n') {
			if (tmp == '1') {
				s.push(tmp);
			}
			else if (tmp == '0' && s.size() == 0) {
				num_0++;
			}
			else {
				chenben += s.size()+1;
				num_0++;
			}
		}
		//printf("%lld\n", chenben);
		cout << chenben << "\n";
	}
	return 0;
}

【错误代码】

#define _CRT_SECURE_NO_WARNINGS 1

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
	int t;scanf("%d",&t); getchar();

	for (int i = 0; i < t; i++) {
		stack<char> s;
		char tmp;
		int num_0 = 0;
		int chenben = 0;

		while (~scanf("%c", &tmp) && tmp != '\n') {
			if (tmp == '1') {
				s.push(tmp);
			}
			else if (tmp == '0' && s.size() == 0) {
				num_0++;
			}
			else {
				chenben += s.size()+1;
				num_0++;
			}
		}
		printf("%d\n", chenben);
	}
	return 0;
}

收获:
刚开始用了一个笨方法 时间复杂度是 N*N
后来改成了栈,其实用其他的也行,主要是我太懒了,就用了这个,这样就只有 N 了。
But! 我在改完代码后居然还是过不了!搞了半天原来是数据范围超了,我就直接搞上 #define int long long 了。以后要多加注意(与 signed main())一同进行食用😋

  • 35
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值