东三省CCPC区域赛

整体来说题目难度不算很高,比较考验思维能力。

F、年少的誓约

题目链接:sdccpc20250528 - Virtual Judge

本题主要是在于思维方式,如果按照题意用所给的原时间去找目标时间的话情况非常的多,而且没什么规律性。但是如果直接枚举所给范围中的时间,计算每个时间点与原来时间之间的角度,最后再取最小值。这样的话就非常的清晰,处理起来也非常的方便。接下来看代码,代码中也有比较清晰的注释。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second
const int N = 1e6+5;
// 计算时针转动的角度(从0点0分开始)
double ho(int h, int m)
{
    return (h * 30 + m * 0.5);
}

// 计算分针转动的角度(从0点0分开始)
double mi(int m)
{
    return (m * 6);
}

void solve()
{
    int x0, y0, x1, y1, x2, y2;
    cin >> x0 >> y0 >> x1 >> y1 >> x2 >> y2;
    double minn = 1e9;
    int besth = -1, bestm = -1;// 遍历起始时间到结束时间的所有时刻
    for (int h = x1; h <= x2; h++)
	{
        int sm = (h == x1) ? y1 : 0;
        int em = (h == x2) ? y2 : 59;
        for (int m = sm; m <= em; m++)
		{
            double h0 = ho(x0, y0);
            double h1 = ho(h, m);
            double m0 = mi(y0);
            double m1 = mi(m);// 计算时针和分针需要转动的角度(考虑顺时针和逆时针的最小角度)
            double ha = min(fabs(h1 - h0), 360 - fabs(h1 - h0));
            double ma = min(fabs(m1 - m0), 360 - fabs(m1 - m0));
            double cost = ha + ma;// 如果代价更小或者代价相同但时间更早,更新最佳时间
            if (cost < minn || (cost == minn && (h < besth || (h == besth && m < bestm))))
			{
                minn = cost;
                besth = h;
                bestm = m;
            }
        }
    }
    cout << besth << " " << bestm << endl;
}
signed main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
    cin >> t;
    while(t--) solve();
    return 0;
}

G、加边

题目链接:sdccpc20250528 - Virtual Judge

本来以为是图呢,其实就简单统计一下就行了

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second
const int N =  1e6+5;
int a[N];
int n,m;
int x,y,cnt,sum;
string s;
vector<int> v;
void solve()
{
	cin >> n >> m;
	for(int i=1; i<=m; i++)
	{
		cin >> x >> y;
		a[x]++,a[y]++;
	}
	for(int i=1; i<=n; i++)
	{
		if(a[i]%2==1) v.push_back(i);
	}
	if(v.size()%2==0)
	{
		cout << v.size()/2 << endl;
		for(int i=0; i<v.size(); i+=2)
		{
			cout << v[i] << ' ' << v[i+1] << endl;
		}
	}
	else 
	{
		cout << v.size()/2+1 << endl;
		for(int i=0; i<v.size()-1; i+=2)
		{
			cout << v[i] << ' ' << v[i+1] << endl;
		}
		cout << v[v.size()-1] <<' ' << v[v.size()-1];
	}
}

signed main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1; 
//	cin >> t;
	while(t--) solve();
	return 0;
 } 

I、王国-----求测

题目链接:

这个题比想象的要简单一些。题目翻译一下就是有两排点,第一排是1~n,第二排是n+1~2n.第一排的每个点都会与一个第二排的点犯冲,也就是不能走这个点,给你两个城市看能不能到达。

如果目标的两个点犯冲,那么就一定不行。如果n>2,这个时候总能找到一个点能试两个城市链接起来。因为每个城市最多与一个城市犯冲,那么同一排的城市要想互通只需要两条路。所以当n>2的时候总能找到一条路使得两个城市互通。特殊判断:如果自己到自己的话就一定可以。当n=2时,如果目标的两个城市之间不犯冲,而且他们不在同一排的话,也可以到达。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second
const int N =  2e5+5;
int a[N];
int n,s;
int x,y,cnt,ans;
//string s;
vector<int> v;
map<pii, int> m;
void solve()
{
	m.clear();
	int t;
	cin >> n >> s >> t;
	for(int i=1; i<=n; i++)//如果1,3 
	{
		cin >> x;
		m[{i,x}]=1;
		m[{x,i}]=1;
	} 
	if(s==t)
	{
		cout << "Yes" << endl;
		return ;
	}
	if(m[{s,t}]==1)
	{
		cout << "No" << endl;
		return ;
	}
	else
	{
		if(n>2)
		{
			cout << "Yes" << endl;
			return ;
		}
		else if(n==1){
			cout << "No" << endl;
			return ;
		}
		else if(n==2)
		{
			if((s<=n&&t<=n)||(s>n&&t>n))
			{
				cout << "No" << endl;
				return ;
			}
			else
			{
				cout << "Yes" << endl;
				return ;
			}
		}
	}
}

signed main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1; 
	cin >> t;
	while(t--) solve();
	return 0;
 } 

K、微信小游戏

题目链接:sdccpc20250528 - Virtual Judge

本题意思是有一个小方块可以放在每一列的最上边并将本列最下边的方块给推下去。求解最终使每一列颜色相同且列与列之间颜色不同所需要的最少操作数是多少。首先每一列的颜色应该最大程度的由当列的第一排决定,如果第一排都换掉的话整列都要换掉了。如果第一排的颜色有重复的话那么就意味着一定有的列要推倒全部重来。那么这个时候就要判断到底是让同样颜色的那一列重来。留下的是从上到下连续相同颜色块数最多的那一列。因为连续的越多最下面需要换掉的就越少。最后计算一下到底有几次操作就行了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second
const int N =  2e3+5;
int a[N][N];
int n,m;
int x,y,cnt,ans;
string s;
vector<int> v;
map<int, int> mp;
void solve()
{
	cin >> n >> m;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			cin >> a[i][j];

	for(int i=1; i<=m; i++)
	{
		cnt=1;
		for(int j=2; j<=n; j++)
		{
			if(a[j][i]==a[1][i])
				cnt++;
			else break;
		}
		mp[a[1][i]]=max(mp[a[1][i]],cnt);
	}

	for(int i=1; i<=m; i++)
		ans+=n-mp[i];
	cout << ans;
}

signed main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
//	cin >> t;
	while(t--) solve();
	return 0;
 }

本次比赛还行吧,F题思路没转过来挺可惜的,前面的题思路来的越来越快了,继续加油吧!

好了,本次的补题就到这里了~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值