ACM寒假集训第一次专题任务

ACM寒假集训第一次专题任务

一、

题目:Long Loong

联想截图_20250123175945

联想截图_20250123180005

解题思路:

因为o出现次数由输入的x所决定,可以想到使用一个循环解决。

AC代码:

#include<iostream>
using namespace std;
int main()
{
	int X;
	cin>>X;
	cout<<"L";
	for(int i=1;i<=X;i++)
	{
		cout<<"o";
	}
	cout<<"ng";
	system("pause");
	return 0;
}

二、

题目:YES or YES?

联想截图_20250123181440

解题思路:

使用循环将t个字符串全部输入字符串数组并全部转换成小写后与”yes“进行比较。

AC代码:

#include<iostream>
#include<string>
#include<cctype>
using namespace std;
int main()
{
	int t;
	cin>>t;
	getchar();
	string s[t+1];
	for(int i=0;i<t;i++)
	{
		getline(cin,s[i]);
		for(int j=0;j<3;j++)
		{
			s[i][j]=tolower(s[i][j]);
		}
		
	}
	for(int i=0;i<t;i++)
	{
		if(s[i]=="yes")
		{
			cout<<"YES"<<endl;
		}
		else
		{
			cout<<"NO"<<endl;
		}
	}
	system("pause");
	return 0;
}

注意:

cin在读取字符串时,会跳过前导的空白字符(像空格、制表符、换行符),并且在遇到下一个空白字符时停止读取。cin 会把换行符留在输入缓冲区里。这可能会对后续使用 getline 读取输入造成影响。(可在getline之前用cin.ignore()清除输入缓冲区里的换行符)

getline 是一个函数,定义于 <string> 头文件中。它会从输入流里读取一行内容,直至遇到换行符为止,并且会把换行符从输入缓冲区中移除。

三、

题目:Even? Odd? G

联想截图_20250123182208

联想截图_20250123182225

解题思路:

因为要判断的正整数可能很长,所以用字符串数组接收。通过字符串最后一位数字判断奇偶(查ASCII表可知偶数对应ASCII码也为偶数,可以直接判断)。

AC代码:


#include<string>
using namespace std;
int main()
{
	int N;
	cin>>N;
	cin.ignore();
	char n[110];
	string s[110];
	for(int i=0;i<N;i++)
	{
		cin>>s[i];
		n[i]=s[i].back();
	}
	for(int i=0;i<N;i++)
	{
		if(n[i]%2==0)
		{
			cout<<"even"<<endl;
		}
		else
		{
			cout<<"odd"<<endl;
		}
	}
	return 0;
}

四、

题目:Problem Generator

联想截图_20250123183235

联想截图_20250123183247

解题思路:

t确定几轮测试,每轮测试需要明确比赛轮数m和代表题目的字符串a(n看起来可有可无),遍历a并统计每个难度出现的次数,再判断每个难度次数是否达到要求。统计题目缺少个数并记入数组,测试循环结束后遍历数组输出。

AC代码:

#include<iostream>
#include<string>
#include <algorithm> 
using namespace std;
int main()
{
	int t;
	cin>>t;
	int sum[1010]={0};
	for(int i=0;i<t;i++)
	{
		int n,m,c[7],T;
		fill(c,c+7,0);
		cin>>n>>m;
		string a;
		cin>>a;
		for(auto p=a.begin();p!=a.end();p++)
		{
			if(*p=='A')
			{
				c[0]++;
			}
			else if(*p=='B')
			{
				c[1]++;
			}
			else if(*p=='C')
			{
				c[2]++;
			}
			else if(*p=='D')
			{
				c[3]++;
			}
			else if(*p=='E')
			{
				c[4]++;
			}
			else if(*p=='F')
			{
				c[5]++;
			}
			else if(*p=='G')
			{
				c[6]++;
			}
		}
		for(int j=0;j<7;j++)
		{
			T=m-c[j];
			if(T>0)
			{
				sum[i]+=T;
			}
		}
	}
	for(int i=0;i<t;i++)
	{
		cout<<sum[i]<<endl;
	}
	return 0;
}

注意:

1、迭代器for(auto p=a.begin();p!=a.end();p++)

​ 这种迭代器遍历方式适用于所有提供了 begin()end() 成员函 数的容器,例如 std::vectorstd::liststd::set 等。

2、std::fill 函数定义于 <algorithm> 头文件中

​ 原型:void fill( ForwardIt first, ForwardIt last, const T& value );

first:指向要填充元素范围起始位置的迭代器。
last:指向要填充元素范围结束位置的下一个位置的迭代器。
value:要赋给指定范围内每个元素的值。

fill(c, c + 7, 0); 的具体分析

  • c:在 C++ 里,数组名可以隐式转换为指向数组首元素的指针,所以 c 相当于指向数组 c 第一个元素的指针,也就是迭代器。
  • c + 7:指针算术运算,它指向数组 c 第 7 个元素之后的位置。
  • 0:要赋给数组元素的值。

五、

题目:rules

联想截图_20250123183852

联想截图_20250123183927

解题思路:

直接将题目翻译成编程语言可得

AC代码:

#include<iostream>
using namespace std;
int main()
{
	int n,m,k,r,SUM=0;
	cin>>n>>m>>k;
	for(int i=0;i<m;i++)
	{
		int sum=0;
		for(int j=0;j<n;j++)
		{
			cin>>r;
			if(r==k)
			{
				sum++;
			}
		}
		if(sum*2>=n)
		{
			SUM++;
		}
	}
	if(SUM*2>=m)
	{
		cout<<"YES"<<endl;
	}
	else
	{
		cout<<"NO"<<endl;
	}
	return 0;
}

六、

题目:Many Replacement

联想截图_20250123184312

联想截图_20250123184337

联想截图_20250123184357

解题思路:

(直接翻译题目会超时)使用结构体数组构建映射表,将所有的置换操作按顺序输入;然后从'a'至'z'每一个字母都遍历一次映射表,并将此字母的变换终点[1]输入一个新的字符串fc[2],此字符串将作为最终的映射表承担对目标字符串S的变换任务。遍历S中的元素,并通过S[i]-'a'将S中的第i个元素转换成fc对应下标[3],将fc[S[i]-'a']输出。

AC代码:

#include<iostream>
#include<string>
using namespace std;
struct replace{
	char fr;
	char to;
};
int main()
{
	int N;
	string S;
	int Q;
	string fc;
	replace c[200000];
	cin>>N;
	cin>>S;
	cin>>Q;
	for(int i=0;i<Q;i++)
	{
		cin>>c[i].fr>>c[i].to;
	}
	for(char io='a';io<='z';io++)
	{
		char o=io;
		for(int i=0;i<Q;i++)
		{
			if(o==c[i].fr)
			{
				o=c[i].to;
			}
		}
		fc[io-'a']=o;
	}
	for(int i=0;i<(int)S.size();i++)
	{
		cout<<fc[S[i]-'a'];
	}
	return 0;
}

七、

题目:更好的交换

联想截图_20250123184750

联想截图_20250123184817

联想截图_20250123184837

解题思路:

(直接翻译题目会超时)所以观察示例1:

1 2 3
1 4 5 6
2 3 2 1
3 9 8 7

经过变换:

1 3 2
1 4 6 5
2 3 1 2
3 9 7 8

可知,变换不改变这些元素在二维数组中的下标(包括行列)。那么,只需要明确以上表格中加粗部分的最终位置即可确定最终表格。

先在输入数据的同时分别存储初始行列编号,tagx[1100]tagy[1100]分别存储行列编号,下标为正常顺序,储存值为位于当前行(列)的行(列)[4]。再经过m次行(列)变换,直接遍历tagx[]tagy[]即为所求表格。

AC代码:

#include<iostream>
#include <utility>
using namespace std;
int main()
{
    int n,m,a[1100][1100]={0},tagx[1100],tagy[1100];
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
        }
        tagx[i]=tagy[i]=i;
    }
    for(int op,x,y,i=1;i<=m;i++)
    {
        cin>>op>>x>>y;
        if(op==1)
        {
            swap(tagx[x],tagx[y]);
        }
        else
        {
            swap(tagy[x],tagy[y]);
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(j!=1)
            cout<<" ";
            cout<<a[tagx[i]][tagy[j]];
        }
        cout<<"\n";
    }
    return 0;
}

注意:

std::swap 定义在 <algorithm><utility> 头文件中,在 C++11 及以后版本中,推荐包含 <utility> 头文件。

它接受两个同类型对象的引用作为参数,然后交换它们的值。

学习总结

语法:

cin在读取字符串时,会跳过空白字符,并且在遇到下一个空白字符时停止读取,且会把换行符留在输入缓冲区

getline 定义于 <string> 头文件中。它会从输入流里读取一行内容,直至遇到换行符为止,并且会把换行符从输入缓冲区中移除。

以上二者都不包含结束符。

C++语法糖:

一、auto的使用:

​ 1、编译器会根据赋给变量的值自动推导变量类型(必须要赋值)

​ 2、范围for循环for(auto ai : a)

二、Lambda表达式:

​ 基本语法: [capture list] (parameter list) -> return type { function body }

捕获列表(capture list):用于指定 Lambda 表达式可以访问的外部变量。它可以为空,也可以包含一个或多个变量,变量之间用逗号分隔。捕获方式有值捕获和引用捕获两种。

参数列表(parameter list):与普通函数的参数列表类似,用于传递给 Lambda 表达式的参数。可以为空。

返回类型(return type):指定 Lambda 表达式的返回类型。如果 Lambda 表达式的返回类型可以由编译器自动推导得出,这部分可以省略。

函数体(function body):包含 Lambda 表达式要执行的代码。

​ 例如:

#include <iostream>

int main() {
    auto add = [](int a, int b) { return a + b; };
    int result = add(3, 5);
    std::cout << "3 + 5 = " << result << std::endl;
    return 0;
}

auto add = [](int a, int b) { return a + b; };

时空复杂度:

040645e4b622b0ef842ad0f1e0505083

时间复杂度默认指最大时间复杂度

空间复杂度是衡量程序内存占用的量度,它是变量定义次数的化简结果,采用和时间复杂度完全相同的记号和化简规则。

STL的使用:

​ 1、sort:快速排序,时间复杂度O(nlog(n)),默认用小于号排序,区间左闭右开

​ 2、reverse:翻转元素,时间复杂度O(n),区间左闭右开

​ 3、lower_bound / upper_bound:二分查找,时间复杂度O(log(n))

​ lower_bound:在有序序列中二分查找「第一个大于等于给定值」的元素,并返回它的迭代器。

​ upper_bound: 用于查找「第一个大于给定值」的元素,用法与lower_bound相同。

​ 4、常用的STL容器:pair
​ stack
​ queue
​ priority_queue
​ vector
​ deque
​ list
​ set
​ map
​ string


  1. 例如,'a'->'b','b'->'c',且此后不再有针对'c'的变换,即可称'c'为'a'的变换终点。 ↩︎

  2. 其中下标0所对应的元素为'a'的变换终点,1为'b'的变换终点,以此类推。 ↩︎

  3. 例如,若S[i]'a',则S[i]-'a'0。 ↩︎

  4. 例如,tagx[3]==5意味着目前初始表格的第5行在原表格第3行。 ↩︎

posted @ 2025-01-23 23:56  cytlllll  阅读(38)  评论(1)    收藏  举报