ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UPC2022暑期个人训练赛第32场

2022-08-12 01:02:15  阅读:142  来源: 互联网

标签:输出 include int 32 样例 MM 窨井盖 训练赛 UPC2022


问题 A: 窨井盖

题目描述

Jzt小时候走路的时候,有一个习惯,踩着窨井盖走。(不知道有没有人小时候也有这种做法……)
踩窨井盖很爽,但是,jzt不希望走得太慢,因此,他希望每一步走过的距离的最小值最大。为了快一点走,jzt只好忍痛割爱,跳过一些窨井盖。但是,如果跳过太多,又会觉得不爽,因此,他决定,最多可以跳过M个窨井盖。
你可以认为jzt的腿无限长,不用担心一步跨不到……

输入

第一行三个数L,N,M,分别表示家的位置,有N个窨井盖,可以跳过M个窨井盖。
接下来N行,每行一个数Di,表示N个窨井盖的位置

输出

输出一行一个数,表示最小距离的最大值。

样例输入

25 5 2
2
14
11
21
17

样例输出

4

提示

样例解释:跳过位置2和位置14的窨井盖,剩下相邻的窨井盖中距离最小的是4,是17到21或者21到25

1<=L<=1,000,000,000
0<=N<=50,000
0<=M<=N
0<Di<L
50%的数据,N<=100

一开始想作差然后排个序,选第m+1个,后来发现跳过井盖后,某些差值会变大,所以这个思路不行。不行,咱就枚举试试呗,但是鉴于1e9的数据量,用二分可以解决

代码

#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
int l,m,n;
int d[50005];
signed main()
{
    cin>>l>>n>>m;
    for(int i=1;i<=n;i++)
    cin>>d[i];
    d[n+1]=l;
    sort(d,d+1+n);
    int ll=1,r=l+1,mid;
    while(ll<r)
    {
        mid=ll+r+1>>1;//因为mid是减一的避免死循环
        int k=0,q=0;//k是最小跳过距离为m时一定跳过的井盖的数量
        for(int i=1;i<=n+1;i++)
        {
            if(d[i]-q<mid)k++;//小于的才跳
            else q=d[i];
        }
        if(k>m)r=mid-1;//k>m说明这个m不可行
        else ll=mid;
    }
    cout<<ll;
    return 0;
}

问题 B: 约会序列

题目描述

众所周知,HYF有很多小姊妹。
HYF的小姊妹军团共有N个人,他每天选择一个不同的MM约会。现在HYF想把未来的N天里要约会的MM做一个计划……
首先,他按照自己的标准把N个MM分成A等~Z等,当然A等是质量最好的,Z等是质量最差的(可怜的Z等MM……),然后把她们随机地排成一个队列,比如ACDBCB。HYF决定每次选择队列最前或最后的MM约会,约过的MM就从队列中删去,这样就得到一个长度为N的约会序列。不同的选择方式会得到不同的约会序列,贪心的HYF当然希望先约质量高的MM啦!所以他希望得到所有约会序列中字典序最小的那个。
请你写一个程序帮他确定这样的约会序列。

输入

第一行一个正整数N,表示一共N个MM
接下来N行,每行一个大写字母,表示队列中第i个MM的级别

输出

一行一个长度为N的字符串,表示约会序列中字典序最小的那个。

样例输入

6
A
C
D
B
C
B

样例输出

ABCBCD

提示

30%的数据,N<=20
60%的数据,N<=100
100%的数据,N<=2000
这题。一开始死活55分把我挡住了,重写了一个没想到意外过了
就是在处理相同字母时需要考虑下,之前的策略是输出一个,然后到不行(两指针相等或者字母不等时判断下),估计有bug的,后来干脆输出交给下一波循环吧,数据较小。

代码

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
char s[20010];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)cin>>s[i];
	for(int i=1,j=n;i<=j;)
	{
		if(s[i]<s[j])
		{
			cout<<s[i];
			i++;
		}
		else if(s[i]>s[j])
		{
			cout<<s[j];
			j--;
		}
		else
		{
			int l=i,r=j;
			while(l<=r)
			{
				if(s[l]!=s[r])break;
				l++,r--;
			}
			if(s[l]<s[r])
			{
				cout<<s[i];
				i++;
			}
			else 
			{
				cout<<s[j];
				j--;
			}
		}
	}
	return 0;
}

问题 C: 直角三角形

题目描述

在平面直角坐标系上有N个点。
编写程序,统计出这N个点能构成多少个两直角边分别平行于坐标轴的直角三角形。

输入

输入共有两行:
第1行:输入一个整数N,(3≤N≤500,000);
第2行到N+1行:每行两个正整数X,Y(1≤X,Y≤500,000),代表点的坐标。

输出

输出只有一行,
输出直角三角形的个数。

样例输入

【样例1】
3
4 2
2 1
1 2
【样例2】
6
10 10
20 10
10 20
20 20
30 20
30 30

样例输出

【样例1】
0
【样例2】
8

提示

对于全部40%的数据,保证N≤100;
对于全部70%的数据,保证N≤10,000;
对于全部的数据,保证N≤500,000;

这个题需要坐标系画图,可以用GeoGebra
样例二
image
有些眼花缭乱,我们分析一下,既然是直角三角形,而且直角边平行于坐标轴,那么对于一个点(x,y)它能和它同行和同列的点组成(l-1)*(r-1)个直角三角形,对于每个点枚举相加下就OK了,此题ans开long long
代码

#include<iostream>
#include<map>
#define int long long
using namespace std;
int n,l[500001],r[500001],ans;
struct point
{
	int x;int y;
}a[500001];
signed main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    	scanf("%lld %lld",&a[i].x,&a[i].y);
    	l[a[i].x]++;
    	r[a[i].y]++;
	}
	for(int i=1;i<=n;i++)
	{
		int x=a[i].x,y=a[i].y;
		if((l[x]>1)&&(r[y]>1))
			ans=ans+(l[x]-1)*(r[y]-1);
	}
	cout<<ans;
    return 0;
}

问题 D: 最勇敢的机器人

题目描述

机器人们都想知道谁是最勇敢的,于是它们比赛搬运一些物品。
它们到了一个仓库,里面有n个物品,每个物品都有一个价值Pi和重量Wi,但是有些物品放在一起会爆炸,并且爆炸具有传递性。(a和b会爆炸、b和c会爆炸则a和c会爆炸)机器人们可不想因此损失自己好不容易从Wind那里敲诈来的装备,于是它们想知道在能力范围内,它们最多可以拿多少价值的物品。
你能帮助它们吗?

输入

每组测试数据
第1行为n,Wmax,k(0<=n,Wmax,k<=1000)
接下来n行,为每个物品的Pi,Wi(0<=Pi<=1000,1<=Wi<=10,均为整数)
再接下来k行,每行2个数字a,b表示a和b会发生爆炸

输出

对每组数据输出1行,为最大可能价值

样例输入

3 10 1
100 1
200 5
10 5
1 2

样例输出

210

并查集+背包,最后73分有点小遗憾,我的思路是搞一个结构体,每加入一个物品就把它的f存进去,再加入的话判断一下,CSDN上看到一个不错的思路,同一结构体的存一组,每组只能选一个
我该复习DP和背包了

代码

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#pragma GCC optimize(2)
using namespace std;
int n,wm,k;
int f[1001],t[1001][1001];
int an[1001];
int w[1001],v[1001];
inline int fin(int x)
{
    if(f[x]==x)return x;
    return f[x]=fin(f[x]);
}
inline void un(int x,int y)
{
    int xx=fin(x),yy=fin(y);
    if(xx!=yy)
    f[xx]=yy;
}

signed main()
{
    cin>>n>>wm>>k;
    for(int i=1;i<=n;i++)
    {
        f[i]=i;
        cin>>v[i]>>w[i];
    }
    for(int i=1;i<=k;i++)
    {
        int x,y;
        cin>>x>>y;
        un(x,y);
    }
    for(int i=1;i<=n;i++)
    {
    	int p=fin(i);
    	t[p][++t[p][0]]=i;
	}
    for(int i=1;i<=n;i++)
    {
    	if(t[i][0]==0)continue;
        for(int j=wm;j>=0;j--)//这里不知道会用到哪一个物品,所以为0
        {
        	for(int l=1;l<=t[i][0];l++)
        	{
        		if(j>=w[t[i][l]])
        		an[j]=max(an[j],an[j-w[t[i][l]]]+v[t[i][l]]);
			}
		}
    }
    cout<<an[wm];
    return 0;
}

笔记本电池没电了,剩下明天继续补

标签:输出,include,int,32,样例,MM,窨井盖,训练赛,UPC2022
来源: https://www.cnblogs.com/qbning/p/16578412.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有