2023CCPC哈尔滨 B L M题解

发布于:2024-05-05 ⋅ 阅读:(36) ⋅ 点赞:(0)

B题的题目来源:https://vjudge.net/contest/626585#problem/B
**题意描述:**给定一个公式,判断在这个公式下每个下标i的值与0的关系,大于0输出‘+’,小于0输出‘-’,等于0输出‘0’。
**解题思路:**由公式可以推导出mood[i]=mood[i-1]/2+a[i],单纯只用这一个公式还不够,当数过小或者过大时会超出double的范围,因此我们需要将这些数分成整数与小数两个部分,若mood[i]为偶数时,那么它除以2必然是整数,当它为奇数时,它除以2肯定就含有小数,因此当它为奇数时需要提出它的小数部分(包含正负号)。判断时若整数不为0则整数跟0比较大小即可,若整数为0则小数部分跟0比较大小。
实现代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
using namespace std;
const int N=1e5+5;
int a[N];
void solve(){
	int n;
	cin >> n;
	for(int i=1;i<=n;++i) cin >> a[i];
	int x=0;//存放整数
	double s=0;//存放小数
	for(int i=1;i<=n;++i){
		x+=a[i];//模拟滑动数组
		if(x>0) cout << "+";//当整数部分不为0时按整数部分与0比较大小
		else if(x<0) cout << "-";
		else{
			if(s>0) cout << "+";//若整数部分为0则比较小数部分
			else if(s<0) cout << "-";
			else cout << "0";
		}
	    if(x%2){
	    	s=1.0*x/2.0-(x/2);//可以说小数部分存放的是整数部分的符号
		}
	    x/=2;
	}
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t;
	//cin >> t;
	//while(t--) 
	solve();
	return 0;
}

L题的题目来源:https://vjudge.net/contest/626585#problem/L
**题意描述:**给出2种操作方式,再给定a,b数组,问需要多少种操作才能将a数组变为b数组。
**解题思路:**分析题目可以得出,将a数组在以b数组为冒泡排序的基础上进行排序(相当于a数组最终会变为b数组),每次排序一遍与实际操作差一个操作‘1’,因此只需要在每次排序完补上一个‘1’即可。
实现代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
using namespace std;
const int N=1e5+5;
int a[N],b[N],c[N];
void solve(){
	int n;
	cin >> n;
	for(int i=1;i<=n;++i) cin >> a[i];
	for(int i=1;i<=n;++i){
		cin >> b[i];
		c[b[i]]=i;//在b数组的基础上进行冒泡排序
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n-1;++j){
	   	if(c[a[j]]>c[a[j+1]]){//当a[j]在a[j+1]后边时,需要交换
	   		cout << "2";
	   		swap(a[j],a[j+1]);
		   }
		else cout<< "1";//不需要交换时输出1
	   }
		cout << "1";//每次内层循环结束与实际操作相差一个操作1,因此需要补上1
	}
	cout << endl;		
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t;
	cin >> t;
	while(t--){
	  solve();
	}
	return 0;
}

M题的题目来源:https://vjudge.net/contest/626585#problem/M
**题意描述:**给出2种染色方式,按题目要求染色,当读入的字符串为Render时,输出染色区域。
**解题思路:**定义两个check判断函数,分别用来判断2种染色方式的当前位置是否在合法区域内,需要注意的是这两重循环的循环变量其中一个必须是倒着的,不然所输出的染色区域与实际是相反的。
实现代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
using namespace std;
struct node{
	int x1,x2,y1,y2,r;
	int flag;
	char ch;
};
node a[2010];
int m;
int check(int u,int v,int x,int y,int r)//判断圆内的点是否合法
{
	if((x-u)*(x-u)+(y-v)*(y-v)<=r*r)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
int check1(int u,int v,int x,int x1,int y,int y1)//判断矩形内的点是否合法
{
	if(u>=x&&u<=x1&&v>=y&&v<=y1)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
void solve(){
	int n;
	cin >> n;
	for(int i=1;i<=n;++i){
		string s;
		cin >> s;
		if(s=="Circle"){
			cin >> a[m].x1 >> a[m].y1 >> a[m].r;
			cin >> a[m].ch;
			a[m].flag=1;
			m++;
		}
		else if(s=="Rectangle"){
			cin >> a[m].x1 >> a[m].y1 >> a[m].x2 >> a[m].y2;
			cin >> a[m].ch;
			a[m].flag=2;
			m++;
		}
		else
		{
			int x,y,x1,y1;
			cin>>x>>y>>x1>>y1;
			for(int i=y1; i>=y; i--)//外层需要倒着循环,否则输出图像与实际图像是颠倒的
			{
				for(int j=x; j<=x1; j++)
				{
					char o='.';
					for(int z=m-1; z>=0; z--)
					{
						if(a[z].flag==1)
						{
							if(check(j,i,a[z].x1,a[z].y1,a[z].r))
							{
								o=a[z].ch;
								break;
							}

						}
						else if(a[z].flag==2)
						{
							if(check1(j,i,a[z].x1,a[z].x2,a[z].y1,a[z].y2))
							{
								o=a[z].ch;
								break;
							}
						}
					}
					cout<<o;
				}
				cout<<endl;
			}
		}
	}		
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t;
	//cin >> t;
	//while(t--)
	  solve();
	return 0;
}