牛客寒假算法基础训练营3

1、处女座点名
题目描述
处女座觉得自己手上的经费可能不太够,于是决定给牛逼学生们带家教。
一天他去上课用自己的火眼金睛感觉教室里有一个学生没有来,于是他就叫学生们报出自己的学号。
已知这个班上的学号是从1开始连续编号的,处女座告诉你这个班上有多少人,想问问你到底是谁没有来。

输入描述:
输入数据共两行,第一行为一个整数N,表示班上的学生数量。
第二行为一行N-1个整数,表示已经来的学生的学号,按升序给出。

输出描述:
输出一个整数,为没有来的学生的学号。

示例1
输入
3
1 3
输出
2

备注:
2≤N≤200000

签到题,没什么难度,看看有没有断的就可以了

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int num[200005];
	cin>>num[0];
	if(num[0]!=1)
	cout<<"1"<<endl;
	else
	for(int i=1;i<n;i++)
	{
		cin>>num[i];
		if(num[i]!=num[i-1]+1)
		{
			cout<<i+1<<endl;
			break;
		}		
	}
	return 0;
}

2、处女座和小姐姐
题目描述
既然昨天晚上处女座已经训练了,明天才要交作业,那今天就是平淡无奇要上课的一天了。
然而处女座也想自己的小姐姐了,可是这节课是老师安排座位,处女座坐在(1,1),而小姐姐坐在(n,m)。他们之间只能通过传纸条的方式来交流感情。对于处女座而言,他上课不想过度分心,因此并不想传纸条,只在那里趁机折千纸鹤。
老师上课喜欢用"开火车"的方式让大家轮流回答问题,显然处女座作为(1,1)位,会被第一个叫起来回答,之后老师将依次叫起(2,1),(3,1),….(n,1),(n,2),(n−1,2)⋯(1,2),⋯的人起来回答问题,每个人回答问题需要1秒。处女座在自己回答完以后会以每秒1个千纸鹤的速度折叠,在小姐姐开始回答问题的时候停止折叠。
处女座想知道,他这节课一共要折多少个千纸鹤?

输入描述:
输入文件包含T+1行,第一行包含一个整数T,表示用例组数。
接下来T行,每行包含两个整数n,m表示小姐姐的位置和教室的大小。

输出描述:
对于每一组用例,用一行输出一个整数,表示处女座要折的千纸鹤的个数。

示例1
输入
1
3 3
输出
7

备注:
2≤n,m≤1,000

找规律题,区别在于小仙女在的列为奇数还是偶数,区别一下就可以了

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		int tx,ty,cnt=0;
		cin>>tx>>ty;
		if(ty%2)
		cout<<tx*ty-2<<endl;
		else
		cout<<tx*(ty-1)-1<<endl;
	}
	return 0;
}

3、处女座的训练
题目描述
处女座靠着自己的家教本领赚够了去比赛的钱,于是开启了疯狂训练。在每个夜深人静第二天不收作业的夜晚,他都会开始刷题。
"今日又是一个刷题的夜晚。"他挑选了n道题开始刷,而题太多,刷不掉,理还乱(呜呜)、自己没有解决的题目每分钟都会给他带来bi的疲倦值,而解决每一道题目都需要花费ai分钟的时间。
当然,处女座一般都是考虑清楚了再写题的,所以他在写题的时候都会精神抖擞,也就是说,当前正在写的那一题并不会给他带来任何疲劳。
为了迎接后天要收的作业和明天要遇到的小姐姐,他想让今晚的刷题尽可能的轻松,那请你帮他找出最小所需要的疲倦值吧。

输入描述:
输入数据共包括n+1行,第一行包括一个n表示处女座今晚打算训练的题的数量。接下来n行,每行包括两个整数ai,bi,分别表示处女座刷掉本题要花费的时间和本题每分钟会带来的疲倦值。

输出描述:
一行包括一个整数,表示处女座今晚训练会产生的最小疲倦值。

示例1
输入
6
6 1
4 5
4 3
6 2
8 1
2 6
输出
86

说明
先做第6个题,增加(1+5+3+2+1)*2= 24 点疲倦值,再做第2个题,增加28点疲倦值,随后依次是第3,4,1,5道题,增加16,12,6点疲倦值。总共的疲倦值是24 + 28 + 16 + 12 + 6 = 86点。
备注:
2≤N≤105.
2≤ai≤4⋅106.
1≤bi≤1000

不得不说,这题受教了,对于这种交叉排序贪心,一般两个量一起贪心的话一起相乘就完事了。实在是受教了。另外还有一个用DFS暴力的办法,不知道为什么一直没过。需要注意一下变量的类型,int会越界。

AC代码

#include<bits/stdc++.h>
using namespace std;
struct node{
	int a,b;
};
struct node t[100005];
bool cmp(struct node x,struct node y)
{
	return x.b*y.a>x.a*y.b;
}
int main()
{
	int n;
	long long int cnt=0,sum=0;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>t[i].a>>t[i].b;
		sum+=t[i].b;
	}
		
	sort(t,t+n,cmp);
	for(int i=0;i<n-1;i++)
	{
		sum-=t[i].b;
		cnt+=t[i].a*sum;
	 } 
	 cout<<cnt<<endl;
	return 0;
}

还有个用DFS写的,只对了一个点,实在不知道哪错了,感觉数据量这么大会超时啊

#include<bits/stdc++.h>
using namespace std;
struct node{
	int a;
	int b;
};
int N,NN;
long long int temp,ans=9999999;
int vis[100005];
struct node t[100005];
long long int fun()
{
	int tt=0;
	for(int i=0;i<N;i++)
	{
		if(vis[i]==0)
		tt+=t[i].b;
	}
	return tt;
}
void dfs(int n)
{
	if(NN==0)
	{
		if(ans>temp)
			ans=temp;
		return ;
	}
	for(int i=0;i<N;i++)
	{
		if(vis[i]==0)
		{
			vis[i]=1;
			temp+=fun()*t[i].a;
			NN--;
			dfs(i);
			NN++;
			temp-=fun()*t[i].a;
			vis[i]=0;
		}
	}
}
int main()
{
	cin>>N;
	for(int i=0;i<N;i++)
		cin>>t[i].a>>t[i].b;
	for(int i=0;i<N;i++)
	{
		memset(vis,0,sizeof(vis));
		NN=N-1;
		vis[i]=1;
		temp=t[i].a*fun();
		dfs(i);
	}
	cout<<ans<<endl;	
	return 0;
}

4、处女座的约会
题目描述
处女座放完了"高利贷",拿到了不少的资金,又可以和小姐姐约会啦!(之前不还是攒钱打比赛的吗)现在处女座拿到了一份宁波市旅游地图决定和小姐姐一起去玩耍。他们来到了动物园,去参观里面的动物。但是很不幸的是,他们在游玩的途中遇到了一只恶龙。
恶龙长有n个头,但经过了处女座的调教,恶龙变得善良了一些。它的n个头每个头要么仍是邪恶的头,用“1”表示,要么已经变得善良,用“0”表示,因而恶龙的n个头就可以用n位01串来表示。而此时处女座要发挥自己的勇士形象,要把所有的龙头都变成
0000⋯00完全善良的龙头。每一次,他可以砍掉龙最右侧的一个头,同时龙会在最左侧长出新的一个头,以保证龙头数量不变。如果他砍掉的是一个1,即邪恶的头,他可以决定龙在最左侧会长出什么样的头;但如果他砍掉了一个善良的头,那么玻璃心的恶龙将会在左侧不受控制的长出一个随机的头,既可能是善良的头,也可能是邪恶的头,而且它总会与处女座作对,尽力的破坏他的计划。
现在给你一个恶龙头的初始状态,即一个01串,请帮助处女座判断一下,能否在有限步之内让全部的龙头都变成善良的龙头。
输入描述:
输入第一行T,表示用例组数。
之后T行,每行一个01串S表示龙头的初始状态,“0”表示善良的头,“1”表示邪恶的头。
输出描述:
对于每组数据,处女座能否将全部的龙头变成善良的头,可以的话输出“cnznb”,不可以则输出“ljcnz”(不含引号)。

示例1
输入
1
1111
输出
cnznb
备注:
T≤1000
|S|≤100

注意,这个问题可能没有你想的那么简单。显然,处女座必须把一些1变成0,这样才能让1的数量减少并消失。但是如果只是简单的每次把1变成0,最终不见得能取胜。比如,如果龙头的状态是101,那么去掉最右边的1并选择在左边长出一个0,则龙头会变成010;再把010右边的0去掉后,如果左边仍长出一个1,则龙头又变回了101的状态,如此反复,将永远不能得到000。

神坑,谁能想到居然这么简单,一直输出处女座牛逼就可以,因为不难发现,无论怎么砍,这个01串是一定可以转换为全0串的,想难了

#include<cstdio>

int main(){
    int T;
    char str[105];
    scanf("%d",&T);
    for(int i=0;i<T;i++){
        puts("cnznb");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43849505/article/details/86661217