预备役二招算法测试题解

这次题目出的都是一些偏向于基础的题目,就是一些简单的模拟,思维,以及基础算法(二分,前缀和)

(点击题目标题,进入原题)

我是签到题

题解:就是说给你 t 组数据,然后每组数据输入两个,一个x,一个y,然后先输出其中的最小值,再输出其中的最大值。

#include<bits/stdc++.h>
using namespace std; 

long long x,y;
int main()
{
	long long t;
	cin>>t;
	while(t--)
	{
		cin>>x>>y;
		printf("%lld %lld\n",min(x,y),max(x,y));
	}
	return 0;
}

能否形成不同的矩形

 

 

题解:能够拆开并且拼凑到一起的边一定是偶数,因此,我们就是单纯去模拟就可以了,如果是偶数就去分开,将其拼凑在一起,判断和之前的是否形成了不一样的矩形(纯粹的模拟题,题目上咋说,你去就咋做)

#include<bits/stdc++.h>
using namespace std;
#define int long long

int t;
int a,b;
signed main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
    cout.tie(0);
	cin>>t;
	while(t--)
	{
		int flag=0;
		cin>>a>>b;
		int x=0,y=0;
		if(a%2==0)
		{
			y=2*b;
			x=a/2;
			if(x!=a&&y!=b&&x!=b&&y!=a)
			{
				flag=1;
			}
		}
		if(b%2==0)
		{
			y=b/2;
			x=2*a;
			if(x!=a&&y!=b&&x!=b&&y!=a)
			{
				flag=1;
			}
		}
		if(flag==1)
		{
			cout<<"YES\n";
		}
		else
		{
			cout<<"NO\n";
		}
	}
	return 0;
}

能否形成不同的字符串

题解:这题比第二个还简单,只需要判断是否能够形成不同的字符串,首先就是你得先判断字符串里面是否有不同的字母,如果没有肯定 是NO,如果有不同的字母,输出YES,并且随机交换两个不同的字母输出就行

#include<bits/stdc++.h>
using namespace std; 
string s;
int t;
int flag;
char r[5000005];
int x,y;
int main()
{
	cin>>t;
	while(t--)
	{
		flag=0;
		cin>>s;
		int len=s.size();
		for(int i=1;i<len;i++)
		{
			if(s[i]!=s[i-1])
			{
				flag=1;
				x=i,y=i-1;
			}
		}
		for(int i=1;i<len;i++)
		{
			r[i-1]=s[i];
		}
		r[len-1]=s[0];
		if(flag==0)
		printf("NO\n");
		else
		{
			printf("YES\n");
			for(int i=0;i<len;i++)
		   {
			printf("%c",r[i]);
		   }
		   printf("\n");
		}
	}
	return 0;
}

查找

 

这题唯一考点就是二分查找,并且数据结构课应该讲过(我不怎么听课,我不确定,应该是讲过的)

#include<bits/stdc++.h>
using namespace std;

int n,m;
int a[1000005];
int target,l,r,mid;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&target);
		l=1;r=n;
		while(l<r)
		{
			mid=(l+r)/2;
			if(a[mid]>=target)
			r=mid;
			else
			l=mid+1;
		}
		if(a[l]==target)
		printf("%d ",l);
		else
		printf("-1 ");
	}
	return 0;
}

A. Contest Proposal

这题就是说有n个题目,每个题目的难度为a[i],要求每个题目的难度不大于对应的b[i],每次可以添加一个题目并且删去最难的题目,求最多能添加几个题目

思路很简单,只要a[i]>b[i],那么就将a[i]改成b[i],并且重新对数组进行排序,然后继续比较就行

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll t;
ll n;
ll a[105];
ll b[105];
void solve(){
	ll u = n;
		ll sum = 0;
		for(int i=n;i>=1;i--)
		{
            if(a[i]>b[u])
            {
                sum++;
            }
            else 
			{
                u--;
            }
        }
        printf("%lld\n",sum);
}
int main()
{
    cin>>t;
    while (t--) 
	{
        cin>>n;
        for (int i = 1; i <= n; i++)
        cin>>a[i];
        for (int i = 1; i <= n; i++)
        cin>>b[i];
        solve();
    }
    return 0;
}

B. Sasha and the Drawing

题解:纯思维性题目,做不出来也算正常,这题 自己在本子上画的话,会发现最多只有前n - 1给才能占两个对角线,也就是2*(n-1)个对角线,剩下的一个涂色只能占一个对角线,因此我们通过这个思路去计算即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;

signed main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>k;
		int sum=2*n-2;
		if(k<=(2*n-2)*2)
		{
			if(k%2==0)
			cout<<k/2<<"\n";
			else
		    cout<<k/2+1<<"\n";
		}
		else
		{
			int cnt=2*n-2;
			k-=(2*n-2)*2;
			cnt+=k;
			cout<<cnt<<"\n";
		}
	}
	return 0;
}

P1314 [NOIP2011 提高组] 聪明的质监员

题意:就是说给你n个矿石,然后,这n个矿石都有自己的重量w,以及其价值v,我们有一种判断机制,就是说给你m个区间范围,每次给你一个左边界L和右边界R,我们的计算机理是,这个区间内的大于规定筛选重量W的数量,乘以大于筛选重量的价值,然后将总的算出来的y累加到一起,看看和规定的标准值S最小差多少,输出最小的参数W

思路,我们发现这题数据超大,必然会有优化方法,我们通过上面·的题意可以发现,我们的参数设置的越大,能过筛选的石头越少,得到的y值越小,设置的越小,能筛选过的石头越多,得到的y值越大,因此我们可以用二分(二分的范围就是给的数据的石头的最小值到最大值,但是我们还要扩增范围,最小值减一,最大值加二)然后我们每次二分的就是参数W,然后在计算过程中要用到前缀和优化,我们要去记录出现的大于参数的矿石数目以及总价值,然后我们去计算总的Y值,Y值大于标准值S就说明,我们的参数设置的小了,要增大左边界,要是小于标准值,就说明,我们的参数设置的太大了,要缩小右边界

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,s;
int w[200005];
int v[200005]; 
int l[200005],r[200005];
int maxn=0;
int minn=0x3f3f3f3f3f3f3f3f;
int sumn[200005];
int sumv[200005];
int ans=0;//统计本次筛选的总价值
int mn=0x3f3f3f3f3f3f3f3f;//统计最小差值 
bool check(int mid)
{
	memset(sumn,0,sizeof(sumn));
	memset(sumv,0,sizeof(sumv));
	int ans=0;//统计总的价值也就是y[i] 
	for(int i=1;i<=n;i++)
	{
		if(w[i]>=mid)
		{
			sumn[i]=sumn[i-1]+1;//统计能过筛查的数量
			sumv[i]=sumv[i-1]+v[i];//统计能过筛查的价值 
		}
		else
		{
			sumn[i]=sumn[i-1];
			sumv[i]=sumv[i-1];
		}
	}
	
	for(int i=1;i<=m;i++)
	{
		ans+=(sumn[r[i]]-sumn[l[i]-1])*(sumv[r[i]]-sumv[l[i]-1]);
	}
	mn=min(mn,llabs(ans-s));
	if(ans>s)
	return true;
	return false;
}
signed main()
{
	cin>>n>>m>>s;
	for(int i=1;i<=n;i++)
	{
		cin>>w[i]>>v[i];
		maxn=max(maxn,w[i]);//二分的上下边界 
		minn=min(minn,w[i]);
	}
	int left,right,mid;
	for(int i=1;i<=m;i++)
	{
		cin>>l[i]>>r[i];
	}
	left=minn-1,right=maxn+2;
	while(left<=right)
	{
		mid=(left+right)/2;
		if(check(mid))
		{
			left=mid+1;
		}
		else
		{
			right=mid-1;
		}
	}
	cout<<mn;
	return 0;
}

 

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值