BNUZ[2021-2-26]BNUZ套题比赛div3

52 篇文章 1 订阅
34 篇文章 0 订阅

A题:
就是有个陷阱,它不是判断“000”和“11”嘛,但是首和尾的话“00”也算不行,就是他这个字符串的全部子串只能是"0","00"或者是“1”不能是“000”“11”,但是开头或者末尾如果是“00”的话也不行,所以要在这个字符串前面加个’0’后面加个’0’,但是如果用char的话不能直接在字符串前面加’0’,必须让整个字符数组往后移一位,那样的话可能会很麻烦,用c++的string对象就可以很快完成这个操作,就是字符串拼接

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	int n;
	cin >> n;
	string str;
	cin >> str;
	str = '0' + str;
	str = str + '0';
	if (str.find("11") != -1)
		printf("No\n");
	else if (str.find("000") != -1)
		printf("No\n");
	else
		printf("Yes\n");
}

B题:
题意:
输入n,再输入n个a[i]表示宽度
‘0’:内向的人,会选择a[i]里面没有人坐的且最大的那个a[i].
‘1’:外向的人,会选择a[i]里面有人坐的且最小的那个a[i].
我是用的三只手(维克托->vector)这个容器来写的,也可以开一个b[20001]的数组去记录,反正都是可以的。

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
struct M
{
	int id, zhi;
}m[200001];
bool cmp(M a, M b)
{
	return a.zhi < b.zhi;
}
int main()
{
	int i,n,j,k=0;
	cin >> n;
	for (i = 0; i < n; i++) {
		cin >> m[i].zhi;
		m[i].id = i;
	}
	string str;
	cin >> str;
	int l = str.length();
	sort(m, m + n, cmp);
	vector<M> zz;
	for (i = 0; i < 2 * n; i++)
	{
		if (str[i] == '0')
		{
			zz.push_back(m[k]);
			cout << m[k].id + 1 << " ";
			k++;
		}
		else
		{
			M t = zz.back();
			zz.pop_back();
			cout << t.id +1 << " ";
		}
	}
}

c题(看了题解也懵懵懂懂):
先看链接->链接:https://blog.csdn.net/PinappleMi/article/details/80549264
他是这么说的:
题意:
给出一个树,如果去掉一条边可以分成两个有偶数个点的连通块(子树)就可以去掉这条边,问最多能去掉几条。

思路:
1.如果奇数肯定去不了,怎么去都不可能分成多个偶数块的
2.如果是偶数,就从顶点1开始,当作父顶点开始dfs,(看了题解才知道dfs,真的菜)。dfs就是计算子树的顶点个数,如果子数是偶数个顶点,那么ans就可以++,然后把该子树标记成搜索过的,最后的答案要-1;因为整棵树肯定是偶数顶点,ans也会+1;
核心思想->链接中的一句话:dfs就是计算子树的顶点个数,如果子树是偶数个顶点,那么ans就可以++,然后把该子树标记成搜索过的。

#include<iostream>
#include<vector>
#include<cstring>
#include<string> 
using namespace std;
const int Max = 1e5 + 5;
vector<int>v[Max];  //存路径 
int vis[Max], ans = 0; //vis 用来标记状态 
int dfs(int x)
{
    int son = 0;   //计算子节点个数 
    vis[x] = 1;
    for (int i = 0; i < v[x].size(); ++i)
    {
        if (!vis[v[x][i]])
        {
            son += dfs(v[x][i]);  //对每个没搜过的节点搜,记录子树顶点。 
        }
    }
    if ((son + 1) % 2 == 0)ans++;  //偶数点的就++,因为整棵树还要加上根节点1个,所以son要+1。 
    return son + 1;
}
int main()
{
    memset(vis, 0, sizeof(vis));
    int n, l, r;
    cin >> n;
    if (n & 1)
    {
        cout << "-1";
        return 0;
    }
    for (int i = 1; i < n; ++i)
    {
        cin >> l >> r;
        v[l].push_back(r);
        v[r].push_back(l);
    }
    dfs(1);
    cout << ans - 1;
    return 0;
}

D题:

#include <stdio.h>
#include <string.h>
int main()
{
	char a[6][15]={"purple","green","blue","orange","red","yellow"}; 
	char b[6][15]={"Power","Time","Space","Soul","Reality","Mind"};
	char c[10][15];
	int i,j,n,m=0,v[10]={0};
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%s",c[i]);
		for(j=0;j<6;j++)
		{
			if(strcmp(c[i],a[j])==0)
			{
				v[j]++;
				m++;
			}
		}
	}
	printf("%d\n",6-n);
	for(i=0;i<6;i++)
		if(v[i]==0)
			printf("%s\n",b[i]);
	return 0;
}

e题:
解题思路:
用数学的方法,比如说当x=5时,y=8时,等式为:x^y 和 y^x(5 ^8和8 ^5),这时可对两边求对数,即为ylnx和xlny(即8ln5和5ln8),比较两边就完事了.
代码如下:

#include<stdio.h>
#include<math.h>
#define ll long long
using namespace std;
int main()
{
    ll x,y;
    scanf("%lld%lld",&x,&y);
    if((double)y*log(x)>(double)x*log(y))
    printf(">");
    else if((double)y*log(x)<(double)x*log(y))
    printf("<");
    else printf("=");
    printf("\n");
    return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值