目录
区间选点
给定N个闭区间[ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。 输出选择的点的最小数量。 位于区间端点上的点也算作区间内。
1<N<1e5
-1e9<ai≤bi≤1e9
输入格式:
第—行包含整数N,表示区间数。 接下来N行,每行包含两个整数a,bi,表示一个区间的两个端点。
输出格式:
一个整数
输入样例:
在这里给出一组输入。例如:
3
-1 1
2 4
3 5
输出样例:
在这里给出相应的输出。例如:
2
思路:首先这是个简单贪心问题。我们根据右端点从小到大排序,如果相等,则根据左端点从小到大排序,如果后一个左端点大于前一个右端点,则答案加一,注意答案初始化要为1。这与另一个经典的贪心问题之安排活动相似,安排活动是根据结束时间从小到大排序,如果相等则按开始时间从小到大排序。
#include<bits/stdc++.h>
using namespace std;
struct Point
{
long long a,b;
}e[100100];
bool compare(Point x,Point y)
{
return x.b<y.b;
if(x.b==y.b)return x.a<y.a;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>e[i].a>>e[i].b;
sort(e+1,e+1+n,compare);
int num=1;
for(int i=2;i<=n;i++)
{
if(e[i].a>e[i-1].b)num++;
}
cout<<num;
return 0;
}
波兰表达式
波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的波兰表示法为+ 2 3。波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的波兰表示法为* + 2 3 4。本题求解波兰表达式的值,其中运算符包括+ - * /四个。
输入格式:
输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数。
输出格式:
输出为一行,表达式的值。
输入样例:
* + 1.0 2.0 + 3.0 4.0
输出样例:
21.000000
注意:atof(),是C 语言标准库(stdlib.h)中的一个字符串处理函数,功能是把字符串转换成浮点数,并将其值返回为double。无法执行有效的转换,该函数将返回 0.000000。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
char vis[10];
double s()
{
scanf("%s",vis);
switch(vis[0])
{
case '+':return s()+s();
case '-':return s()-s();
case '*':return s()*s();
case '/':return s()/s();
default:return atof(vis);
}
}
int main()
{
printf("%lf",s());
return 0;
}
跳一跳 (升级版)
我跳累了~😢
人活着本没有意义,但只有活着就会碰到很多有趣的事,就像你发现了花,而我发现了你一样。
这里有一段整数数组nums,你一开始处于下标为0的第一个元素处,请求出你最少跳几次能到达数组的末尾位置。
当你在i
位置时可以跳跃到一下三个位置:
i + 1
:i+1 < nums.lengthi - 1
:i-1 >= 0j
:nums[i] == nums[j]
输入:
第一行输入n表示nums的长度 第二行以空格分隔输入nums的每个元素
11
11 22 7 7 7 7 7 7 7 22 13
输出:
输出一行最小跳跃次数
3
范围:
- 1 <= nums.length <= 5 * 104
- -108<= nums[i] <= 108
#include<bits/stdc++.h>
using namespace std;
map<int,vector<int>>mp;
int n;
int date[100010],book[100010];
int minn=99999999;
void dfs(int present,int step)
{
if(present==n)
{
if(step<minn)
{
if(step<minn)minn=step;
return;
}
}
if(step>=minn)return;
if(present>1&&book[present-1]==0)
{
book[present-1]=1;
dfs(present-1,step+1);
book[present-1]=0;
}
if(present<n&&book[present+1]==0)
{
book[present+1]=1;
dfs(present+1,step+1);
book[present+1]=0;
}
if(mp[date[present]].size()>1)
{
for(auto v:mp[date[present]])
{
if(book[v]==0)
{
book[v]=1;
dfs(v,step+1);
book[v]=0;
}
}
}
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>date[i];
mp[date[i]].push_back(i);
}
book[1]=1;
dfs(1,0);
cout<<minn;
return 0;
}
社交集群
当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。
输入格式:
输入在第一行给出一个正整数 N(≤1000),为社交网络平台注册的所有用户的人数。于是这些人从 1 到 N 编号。随后 N 行,每行按以下格式给出一个人的兴趣爱好列表:
Ki: hi[1] hi[2] ... hi[Ki]
其中Ki(>0)是兴趣爱好的个数,hi[j]是第j个兴趣爱好的编号,为区间 [1, 1000] 内的整数。
输出格式:
首先在一行中输出不同的社交集群的个数。随后第二行按非增序输出每个集群中的人数。数字间以一个空格分隔,行末不得有多余空格。
输入样例:
8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4
输出样例:
3
4 3 1
思路:每一个人用第一个兴趣编号代表用户,将一个人的兴趣编号用并查集和并起来,这样有相同兴趣的人就被分在了一个组,然后遍历每一个人,查找他的兴趣的父亲节点,然后用一个计数数组技术便可以得到每个圈子有多少人,不为零的个数就是圈子个数。
#include<bits/stdc++.h>
using namespace std;
int fa[1010],book[1010],user[1010];
int findd(int x)
{
if(fa[x]==x)return x;
else
{
fa[x]=findd(fa[x]);
return fa[x];
}
}
void unionn(int x,int y)
{
int dx=findd(x),dy=findd(y);
if(dx==dy)return;
else fa[dx]=dy;
}
bool compare(int a,int b)
{
return a>b;
}
int main()
{
for(int i=1;i<=1000;i++)
fa[i]=i;
int t;
cin>>t;
for(int i=1; i<=t; i++)
{
int k;
char c;
cin>>k>>c>>user[i];
for(int j=1; j<k; j++)
{
int d;
cin>>d;
unionn(user[i],d);
}
}
for(int i=1;i<=t;i++)
book[findd(user[i])]++;
int num=0;
for(int i=1;i<=1000;i++)
if(book[i]!=0)num++;
cout<<num<<endl;
sort(book+1,book+1+1000,compare);
for(int i=1;i<=num;i++)
{
cout<<book[i];
if(i!=num)cout<<" ";
}
return 0;
}
田忌赛马
田忌与齐王赛马,双方各有n匹马参赛,每场比赛赌注为200两黄金,现已知齐王与田忌的每匹马的速度,并且齐王肯定是按马的速度从快到慢出场,现要你写一个程序帮助田忌计算他最好的结果是赢多少两黄金。
说明: 为了简单起见,保证2n匹马的速度均不相同。
输入格式:
输入每组测试数据占3行,第一行是n(n<=1000),表示双方参赛马的数量,第2行n个正整数,表示田忌的马的速度,第3行n个正整数,表示齐王的马的速度.测试数据以“0”结束。
输出格式:
每组测试数据输出一行数据,表示田忌比赛的最好结果是赢多少两黄金。
输入样例:
3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0
输出样例:
200
0
0
思路:这是简单贪心问题,我们把田忌的马和齐王的马从大到小排个序
情况1:如果田忌最大的马比齐王最大的马快,则答案加200
情况2:如果田忌最慢的马比齐王最慢的马快,则答案加200
情况3∶如果田忌最慢的马比齐王最快的马慢,则答案减200(也就是用最慢的马去耗qw最快的马)
情况4:如果田忌最慢的马和齐王最快的马一样快,且不符合以上三种情况,那么肯定这2n匹马的速度相同,故不需要对答案做操作
#include<bits/stdc++.h>
using namespace std;
int a[1010],b[1010];//田忌,齐王
bool compare(int a,int b)
{
return a>b;
}
int main()
{
int n;
cin>>n;
while(n!=0)
{
for(int i=1; i<=n; i++)
cin>>a[i];
for(int i=1; i<=n; i++)
cin>>b[i];
sort(a+1,a+1+n,compare);
sort(b+1,b+1+n,compare);
int ans=0;
int n1=1,n2=1,m1=n,m2=n;
for(int i=1;i<=n;i++)
{
if(a[n1]>b[n2])
{
ans+=200;
n1++;
n2++;
}
else if(a[m1]>b[m2])
{
ans+=200;
m1--;
m2--;
}
else
{
if(a[m1]<b[n2])
{
ans-=200;
m1--;
n2++;
}
}
}
cout<<ans<<endl;
cin>>n;
}
return 0;
}