——考核补题合集

1 篇文章 0 订阅
1 篇文章 0 订阅

下面是本次考核的补题:

序列树

在O. michestep王国,有一棵名叫Habaritran的树,树上有一个长度为 n 的序列 a,由于树的营养 不足,序列只由 0 和
1 构成,修理工Mitchell mitt觉得序列中每个连续的长度为 k 的子串中的0 与1
数量都相同,这棵树才看起来很nice。当然,修理工Mitchell mitt可以将序列中任何一个 0 修改成
1,也可以将任何一个1修改为0,请问修理工Mitchell mitt最少需要修改多少次,才能将这棵树变得nice。

输入

第一行包含两个正整数,分别为 n和k
第二行包含 n个数,每个数为 0 或者 1

输出

输出一行包含一个正整数,表示最少次数,如果序列怎么修改都不能让这棵树变nice,那么输出"-1"(不包含引号)

样例输

8 3
10100010

样例输出

-1

提示 数据范围 1 <= k <= n <= 10^6

对前k个字符串进行处理,不断变换起始点遍历,从而实现对每个位置需要变零和变一数量的掌控;
对获取到的前K个位置进行变化数量的排序,因为x,y的数量要相等,于是我们取能变化最少的x,与变化最少y 即是以x-y升序排列前取x后取y即可实现总数的最小化

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=103;
char t[maxn];
struct pt{
	int x,y,z;
}p[maxn];
bool cmp(pt m,pt n)
{
	return m.z <n.z ;
}
int n,k,m;
int main()
{
	cin>>n>>k;
	cin>>t;
	if(k%2)
	{
		cout<<"-1"<<endl;
	}
	else
	{
		for(int i=0;i<k;i++)
		{
				for(int j=i;j<n;j+=k)
				{
				if(t[j]=='0')
				p[i].x++;
				else 
				p[i].y++;}
	p[i].z=p[i].x-p[i].y;}
				
	
	sort(p,p+k,cmp);
	int ans;
	for(int i=0;i<k/2;i++)ans+=p[i].x;
	for(int i=k/2;i<k;i++)	ans+=p[i].y;
	cout<<ans<<endl;}
	return 0;
	
 } 

广播系统

为了更加快速的传递学习任务,ACM集训队计划建设一个广播系统!按照规划,这个系统包含若干端点,这些端点由神奇的网络连接。 此网络有下述特点:
1.消息可以在任何一个端点产生,并且只能通过这个网络传递信息。每个端点接收消息后会将消息传送到与其相连的端点(单项传输,不会传输到那个消息发送过来的端点)
2.如果某个端点是产生消息的端点,那么消息将被传送到与其相连的每一个端点。
3.当消息在某个端点生成后,其余各个端点均能接收到消息
4.任意一个消息可以被快速的传给所有端点 现给你这个广播系统的连接方案,你能判断此系统是否符合以上要求并且传递给所有的端点?

输入

输入包含多组测试数据。每两组输入数据之间由空行分隔。
每组输入首先包含2个整数N和M,N(1<=N<=1000)表示端点个数,M(0<=M<=N*(N-1)/2)表示通信线路个数。
接下来M行每行输入2个整数A和B(1<=A,B<=N),表示端点A和B由神奇的网络相连。两个端点之间至多由一条网络直接相连,并且没有将某个端点与其自己相连的网络。
当N和M都为0时,输入结束。

输出

对于每组输入,如果所给的系统描述符合题目要求,则输出Yes,否则输出No。

样例输入

4 3
1 2
2 3
3 4

3 1
2 3

0 0

样例输出

Yes
No

这题是普通的并查集,但有一点不同的是要判断环状结构。

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=10005;
int fa[maxn],rk[maxn];
void inti(int n)
	{
	for(int i=1;i<=n;i++)
		{
		fa[i]=i;
		rk[i]=0;}//初始化各节点
		
	}
int find(int x)
	{
		if(fa[x]==x)
		return x;
		else
		return fa[x]=find(fa[x]); 
	}
void unite(int x,int y)
	{
	x=find(x);
	y=find(y);
		if(x==y)
		return ;
		if(rk[x]<rk[y])
		fa[x]=y;
		else 
		{fa[x]=y;
		if(rk[x]==rk[y])
		rk[x]++;
	}}
bool same(int x,int y)
{
	return find(x)==find(y);
}//查询函数

int main()
	{	int n,m,a,b;
		while(cin>>n>>m)
		{	int flag=0;int maxx=0;
			if(n==0&&m==0)
			break;
		inti(n);
			int ans=0;
			for(int i=1;i<=m;i++)
			{	cin>>a>>b;

				unite(a,b);
				
		}
			for(int i=1;i<=n;i++)
				maxx=max(maxx,fa[i]); 
			for(int i=1;i<=n;i++)
				{
				if(same(i,maxx))
				ans++;}
				if(ans==n&&m=n-1)//本题的核心步骤,不然只能 AC50%
				printf("Yes\n");
				else
				printf("No\n");
				
			
	}
		return 0;
 	} 

迷宫

这道题是带拐角的bfs,当时卡在了第一步不算拐角没有初始化为-1而初始化为0

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1005;
char a[maxn][maxn];
int  v[maxn][maxn];
struct pt{
	int x;int y;
	int corn;int d;
};
int dx[]={1,-1,0,0};int dy[]={0,0,1,-1};
	int  kk,n,m,p,q,x,y;
	queue<pt>r;
	void bfs()
	{	
		while(!r.empty())
		{if(r.front().x ==p&&r.front().y==q)
			{
		printf("yes\n");return ;
			}
			pt next;
			for(int i=0;i<4;i++)
			{
				next.x = r.front().x+dx[i];
				next.y = r.front().y +dy[i];
				next.corn = r.front().corn;
				next.d = i;
				
					if(	next.d!=r.front().d&&next.d!=-1)	next.corn++;
					if(next.x>0&&next.x <=m&&next.y>0&&next.y <=n&&!v[next.x ][next.y ]&&next.corn<=kk&&a[next.x ][next.y ]=='.')
					{
					v[next.x][next.y ]=1;
					r.push(next);}
				}
				r.pop() ;
				}
				printf("no\n");	
		}
		int main()
		{	int t;
		cin>>t;
		while(t--)
		{
		
			cin>>m>>n;
			for(int i=1;i<=m;i++)
				for(int j=1;j<=n;j++)
				{
					scanf(" %c",&a[i][j]) ;
				}
			scanf("%d%d%d%d%d",&kk,&y,&x,&q,&p);
			pt fs;
			fs.x=x;
			fs.y=y;
			fs.corn=-1;
			fs.d=-1;
			v[x][y]=1;
			r.push(fs);
			bfs();
			memset(v,0,sizeof(v));}
			return 0;
			
		}

令人心动的秋季折扣

类似01背包,dp即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int M = 100 + 20;
int w[M];
int dp[M*100];//动态规划 
int main()
{    int n;
    while (cin>>n) {
        int sum = 0;
        for (int i = 0; i < n; ++i) {
            scanf("%d", &w[i]);
            sum += w[i];}
        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < n; i++)
            for (int j = sum/2; j >= w[i]; j--) {
                if (dp[j] < dp[j-w[i]] + w[i]) {
                    dp[j] = dp[j-w[i]] + w[i];
                    }}  
        printf("%d\n", sum - dp[sum/2]*2);} 
		return 0;
}		
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ctgu20-acm-律

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值