1 模拟

输入输出

while(scanf("%d", &a) != EOF)

image

cin 会将空格作为输入的分隔符,停止当前输入项的读取,继续等待下一个输入项。 会将回车符视为输入分隔符,停止当前输入项的读取,除非回车符是当前输入的首个字符(此时会忽略该回车符,继续等待输入)。

#include 
int main() {
std::string word1, word2;
std::cin >> word1 >> word2;
std::cout << "word1: " << word1 << ", word2: " << word2 << std::endl;
return 0;
}
// 输入 "hello world",输出 "word1: hello, word2: world",因为空格分隔了两个输入项。

getline 会将空格作为正常字符读取,不会作为输入的分隔符。 会将回车符作为输入结束的标志,读取回车符之前的所有字符,并将回车符从输入流中移除。

#include 
#include 
int main() {
std::string line;
std::getline(std::cin, line);
std::cout << "You entered: " << line << std::endl;
return 0;
}
// 输入 "hello world",输出 "You entered: hello world",空格被正常读取。

scanf 当使用%s格式说明符时,会将空格作为输入的分隔符,停止当前字符串的读取;当使用%[^\n]等格式说明符时,可以读取包含空格的字符串。

1)艺术与篮球

https://www.luogu.com.cn/problem/P10385

为了防止超时,直接输出答案即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

int tr[10] = { 13,1,2,3,5,4,4,2,2,2 };
int day[13] = { 0, 31,28,31,30,31,30,31,31,30,31,30,31 };
int flag = 0;
int check(string s)
{
	int ans = 0;

	for (int i = 0;i < s.size();i++)
	{
		ans += tr[s[i] - '0'];
		//用int得到asii所以0对应48;
	}
	return ans;
}
signed main()
{
	int answ = 0;
	string i22, i33;
	for (int i1 = 2000;i1 <= 2024;i1++)
	{
		for (int i2 = 1;i2 <= 12;i2++)
		{
			for (int i3 = 1;i3 <= day[i2];i3++)
			{
				int c = 0;
				if (i2 < 10)
					i22 = "0" + to_string(i2);
				else  i22 = to_string(i2);
				if (i3 < 10)
					i33 = "0" + to_string(i3);
				else 	i33 = to_string(i3);
				string s = to_string(i1) + i22 + i33;
				cout << s << endl;
				c += check(s);
				if (c > 50)
				{
					
answ++;
//cout << s << endl;
//cout << answ << endl;
				}
					
				if (i1 == 2024 && i2 == 4 && i3 == 13)
				{
					flag = 1;
					break;
				}



			}
			if (flag == 1)
				break;
		}
		if (flag == 1)
			break;
	}
	//cout << check("20240101") << endl;
	cout << answ + 2;

}
####2)好数

3)刷题统计(入门 不用看)

https://www.luogu.com.cn/problem/P8780

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int ans;
int a, b, n;
int ans3;


signed main()
{
	cin >> a >> b >> n;
	int c = a * 5 + b * 2;
	int ans1 = n / c;
	int ans2 = n % c;
	if (ans2 > 0 && ans2 <= a)
		 ans3 = 1;
	if (ans2 > a && ans2 <= 2*a)
		 ans3 = 2;
	if (ans2 > 2*a && ans2 <= 3*a)
		 ans3 = 3;
	if (ans2 > 3*a && ans2 <= 4*a)
		 ans3 = 4;
	if (ans2 > 4*a && ans2 <= 5*a)
		 ans3 = 5;
	if (ans2 > 5*a && ans2 <= 5*a+b)
		 ans3 = 6;
	if (ans2 > 5 * a + b && ans2 <= 5 * a + 2*b)
		 ans3 = 7;
	
		cout << ans1 * 7 + ans3;
	
}

4)航班时间(如何模拟计算时间差)

https://www.luogu.com.cn/problem/P8665

都换成s,统一单位,然后要注意输入

注意: 去程时间差和回程时间差不是飞机的飞行时间,不一样。因为还有时差参与,我们用的都是当地时间(中,美)

5) 好数

https://www.luogu.com.cn/problem/P10424

注意字符串是从0开始,而且和想要的索引不一样,所以设置所以i1与i区分。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;

string s;
int s1;
int ans;
signed main()
{
	cin >> s1;

	for (int j = 1;j <= s1;j++)
	{
		int flag = 1;
		s = to_string(j);
		int i1 = 1;;
		for (int i = s.size() - 1;i >= 0;i--)
		{
			
			
				if (i1 % 2 == 0)
				{

					if (s[i] == '1' || s[i] == '3' || s[i] == '5' || s[i] == '7' || s[i] == '9')
						flag = 0;
				}
				else {
					if (s[i] == '0' || s[i] == '2' || s[i] == '4' || s[i] == '6' || s[i] == '8')
						flag = 0;
				}
				i1++;
			
		}


if (flag == 1)
		{
			ans++;
			/*cout<< s << endl;*/
		}

	}
			cout << ans<< endl;
	}

6)修剪灌木

https://www.luogu.com.cn/problem/P8781

其实是找规律第一次设置为0,到第二次设置为0所经过的时间就是最大生长

自己写的超时了,并且没有注意循环的交接处,所以没有实现一个圈,在头尾有重复
错误代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 10;
int n;
int a[maxn], mx[maxn];


void ad(int x) {
    for (int i = 1; i <= n; i++) {
        a[i]++;
        mx[i] = max(mx[i], a[i]);
    }
    a[x] = 0;
}

signed main() {
    cin >> n;
    int c = 1000;
    while (c--)
    {
 // 模拟从左到右修剪
    for (int i = 1; i <= n; i++) {
        ad(i);
    }
    // 模拟从右到左修剪
    for (int i = n -1; i > 1; i--) {
        ad(i);
    }
    }
   


    // 输出每棵灌木的最大高度
    for (int i = 1; i <= n; i++) {
        cout << mx[i];
        if (i < n) cout << " ";
    }
    cout << endl;

    return 0;
}
点击查看代码

正确代码

image

7)班级活动

https://www.luogu.com.cn/problem/P9421

有点像分治思想,只可能有三种对答案贡献不一样的情况,枚举这三种情况求解

image

自己写
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn];
int n, x;
int ans, maxx, ans1, ans2, ans22;
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int n;
	cin >> n;
	for (int i = 1;i <= n;i++)
	{

		cin >> x;
		maxx = max(x, maxx);
		a[x]++;
	}
	for (int i = 1;i <= maxx;i++)
	{
		if (a[i] == 1)
			ans1++;
		if (a[i] > 2)
		{
			ans2++;
			ans22 += a[i];
		}


	}
	ans22 = ans22 - ans2 * 2;
	if (ans1 >= ans22)
		cout << ans22 + (ans1 - ans22) / 2 << endl;
	//ans22全部修改到1,ans1其他部分一半修改一次即可
	else
		cout << ans1 + (ans22 - ans1) ;
	//ans1部分修改到ans1修改一次,剩下的也全部修改

}
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long//好习惯防见祖宗
int n,s,t[100001],ans=0,d=0,ss=0;
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>s;
		t[s]++;//桶来储存每个学号出现情况
	}
	for(int i=1;i<=n;i++){
		if(t[i]>2){
			d+=t[i]-2;//情况2
		}
		if(t[i]!=0&&t[i]<2){
			ss+=2-t[i];//情况3
		}
	}
	if(d>=ss){//情况2、3抵消(就是2多的转到3少的)
		ans+=ss;
		d-=ss;
		ss=0;
	}
	else{
		ans+=d;
		ss-=d;
		d=0;
	}
	cout<<ans+d+ss/2;//加上剩余,ss/2的原因是两个差1的只需要变一次即可
	return 0;
} 

9)劲舞团

https://www.luogu.com.cn/problem/P10899

image

10)回文字符串

https://www.luogu.com.cn/problem/P10905

把左右lqb取出来检查是否能配对,再检查中间。要以左边为基准比较。

左右即使全是lqb也可能不匹配 lqbaaal -> lqb aaa l

自己写
#include<bits/stdc++.h>
#define int  long long
using namespace std;
const int maxn = 2010;
int n, x,k;
int ans, maxx, ans1, ans2, ans22;
char a, b;
int t,t1;
string s;
bool check(int i, int j)
{
	while (i <= j)
	{
		if (s[i] == s[j])
		{
			i++;
			j--;
		}
		else
			return false;
	}
	return true;
}
bool check2(int i, int j)
{
	//对于qaqqqa,lqlqaa会出错  i=0,j=6;   i=3,j=6,所以应该是<=s.size()
	/*if (i + 1 > s.size() - 1 - j)
		return false;*/
	while (i >=0&&j<=s.size())
	{
		if (s[i] == s[j])
		{
			i--;
			j++;
		}
		else
			return false;
	}
	return true;

}
void solve()
{
	
	cin >> s;
	int i = 0, j = s.size() - 1;

	
		while((s[i] == 'l' || s[i] == 'q' || s[i] == 'b')&&i<s.size())i++;
		while ((s[j] == 'l' || s[j] == 'q' || s[j] == 'b') && j>0)j--;
		//忘记检查,即使相等,并不证明全是lqb
		if (j < i)
		{
			cout << "Yes"<<endl;
			return;
		}
		
		if (check(i, j)&&check2(i-1,j+1))
			cout << "Yes" << endl;
		else
			cout << "No" << endl;



}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	
	int T;
	cin >> T;
	while (T--)solve();
		
}
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int T,n;
char s[1000005];
int main(){
	int p1,p2;
	bool flag;
	scanf("%d",&T);
	while(T--){
		scanf("%s",s+1);
		n=strlen(s+1),p1=0,p2=n+1,flag=1;
		while(p2>1&&(s[p2-1]=='l'||s[p2-1]=='q'||s[p2-1]=='b'))  p2--;//计算右指针
		while(p1<p2-1&&(s[p1+1]=='l'||s[p1+1]=='q'||s[p1+1]=='b'))  p1++;//计算左指针
		for(int i=p1+1,j=p2-1;i<j;i++,j--)//判断中间字符串是否回文
			if(s[i]!=s[j]){
				flag=0;
				break;
			}
		if(p2+p1-1>n)  flag=0;//防止MLE
		else
			for(int i=1;i<=p1;i++)//判断左右字符串是否合法
				if(s[p1-i+1]!=s[p2+i-1]){
					flag=0;
					break;
				}
		printf("%s\n",flag?"Yes":"No");
	}
	return 0;
}
####坑点:第一次连击不计入,所以重置时应该是1
自己写
#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int maxn = 2010;
int n, x,k;
int ans, maxx, ans1, ans2, ans22;
char a, b;
int t,t1;
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	
		while (cin >> a >> b >> t)
		{
if (a == b && t - t1 <= 1000)
		{
			k++;
			ans = max(ans, k);
		}
		else k = 1;
		
			t1 = t;
	}
	cout << ans;
	
		
}

11)外卖店优先级

https://www.luogu.com.cn/problem/P8685

now错误增加,同一时间可能一个店又多个订单,或者同一时间多个店有订单。如果时间相邻,只增加,没减少。并且每次都循环n次然后减少造成浪费,一直未出现的店id可以不管,

错误代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e5 + 10;
int st[maxn];
int st2[maxn];
int n, m, t;
struct dn {
	int ts;
	int id;

}d[maxn];
bool cmp(dn d1, dn d2)
{
	if (d1.ts == d2.ts)
		return d1.id < d2.id;
	/*
	* 若 d1.ts 等于 d2.ts,就比较 d1.id 和 d2.id,
	若 d1.id 小于 d2.id,则返回 true,表明 d1 要排在 d2 前面。
	bool要求返回bool
	*/
	else
		return d1.ts < d2.ts;

}
signed main()
{
	cin >> n >> m >> t;
	for (int i = 1;i <= m;i++)
	{
		cin >> d[i].ts >> d[i].id;

	}

	int now = 1;
	sort(d + 1, d + m + 1, cmp);
	//for (int i = 1;i <= m;i++)
	//{
	//	cout << d[i].ts << d[i].id << endl;;

	//}
	for (int i = 1;i <= m;i++)
	{

		if (d[i].ts > now)
		{
			for (int i1 = 1;i1 <= n;i1++)
			{
				if (i1 == i)
					continue;
				int time =  d[i].ts-now ;
				
				
					st[d[i1].id]-=time;
				if (st[d[i1].id] <= 3)
				{
					st2[d[i1].id] = 0;
					//cout <<i<< "  st2=0  " << d[i1].id << endl;
				}


			}
			st[d[i].id] += 2;
			if (st[d[i].id] > 5)
			{
				st2[d[i].id] = 1;
				//cout << i << "  st2=1  " << d[i].id << endl;
			}

			now = d[i].ts;
		}

		else {
			for (int i1 = 1;i1 <= n;i1++)
			{
				if (i1 == i)
					continue;
				st[d[i1].id]--;
			}
			st[d[i].id] += 2;
			if (st[d[i].id] > 5)
				st2[d[i].id] = 1;
			now++;
			/*cout << i << "  st2=0  " << d[i].id << endl;*/
		}
		if (d[i].ts == t)
			break;

	}
	int ans = 0;
	for (int i = 1;i <= n;i++)
	{
		if (st2[i] == 1)
			ans++;

	}
	cout << ans;


}
正确代码
#include<bits/stdc++.h>
using namespace std;
struct node {
	int t, x;
}a[100005];
bool cmp(node x, node y) {
	return x.t < y.t;
	
}
int c[100005], h[100005];
bool v[100005];
void check(int x) {
	if (c[x] > 5) {
		v[x] = 1;
	}
	if (c[x] <= 3) {
		v[x] = 0;
	}
}
int main() {
	int n, m, t, s = 0;
	cin >> n >> m >> t;
	for (int i = 1;i <= m;i++) {
		cin >> a[i].t >> a[i].x;
	}
	//a结构体。v缓存状态,c订单,h上次该店有订单的时间
	sort(a + 1, a + 1 + m, cmp);
	for (int i = 1;i <= m;i++) {
		//两次订单相差时间不超过1
		if (h[a[i].x] + 1 >= a[i].t) {
			c[a[i].x] += 2;
		}
		else {
			//注意要再减1,3 5 其实2-1时刻没有订单,并且先看是否移出缓存再+=2
			c[a[i].x] -= (a[i].t - h[a[i].x] - 1);
			c[a[i].x] = max(0, c[a[i].x]);
			check(a[i].x);
			c[a[i].x] += 2;
		}
		h[a[i].x] = a[i].t;
		//更新订单时间
		check(a[i].x);
	}
	//那些一直没有出现的店直接在这里减,不用浪费资源,并且可能最后记录在,但是题目要求时刻8,那6-8也没有订单也要减去
	for (int i = 1;i <= n;i++) {
		if (h[i] < t) {
			c[i] -= (t - h[i]);
			c[i] = max(c[i], 0);
		}
		check(i);
		if (v[i]) {
			s++;
		}
	}
	cout << s << "\n";
	return 0;
}
posted on 2025-03-26 21:54  Hoshino1  阅读(11)  评论(0)    收藏  举报