2021年度训练联盟热身训练赛第一场

2021年度训练联盟热身训练赛第一场

题号 题目 通过率
A Weird Flecks, But OK 667/1259
B Code Names 450/1433
C New Maths 348/856
D Some Sum 1522/3277
E Early Orders 688/2891
F Pulling Their Weight 1124/2532
G Birthday Paradox 162/386
H On Average They’re Purple 948/2167
I Full Depth Morning Show 212/341
J This Ain’t Your Grandpa’s Checkerboard 1352/1867
K Solar Energy 102/812

D.Some Sum

题意:

你的朋友偷偷地选了N个介于1和100之间的连续的整数,并希望您猜测它们的和是否为偶数或奇数。
如果总和必须是偶数,则输出 even ;
如果总和必须是奇数,则输出 odd ;
如果和可以是偶数也可以是奇数,输出 Either 。

题解:

枚举出规律
当N=1时,可能为偶数也可能为奇数
当N=2时,两个连续的数的和,那么一定是奇数+偶数,奇数+偶数一定等于奇数
当N=3时,可能为偶数也可能为奇数
当N=4时,一定是偶数
当N=5时,可能为偶数也可能为奇数
当N=6时,一定是奇数
当N=7时,可能为偶数也可能为奇数
当N=8时,一定是奇数
当N=9时,可能为偶数也可能为奇数
当N=10时,一定是偶数
总结:
N是奇数,什么都有可能
N是偶数,如果n/2还是偶数,结果就是偶数
N是偶数,如果n/2还是奇数,结果就是奇数

代码:

#include <iostream>
using namespace std;
int main()
{
    
    
    int n;
    cin>>n;
    if(n%2!=0)  //如果输入的n是奇数,那么得到的和可能为奇数也可能为偶数
        cout<<"Either";
    else      //如果输入的n是偶数
    {
    
    
        if(n/2%2==0)    //如果 偶数/2 还是偶数,那么结果一定为偶数
            cout<<"Even";
        else             //如果 偶数/2 为奇数,那么结果一定为奇数
            cout<<"Odd";
    }
    return 0;
    
    
}

F.Pulling Their Weight

题意:

n个数,让你选一个t,然后比t小的放一侧,比t大的放一侧,要求两侧一样大,问t最小是多少?
(如果和t一样大,奇数个就丢掉一个,剩下偶数个平分,偶数个就直接平分)

题解:

预处理前缀和
我想的二分,二分mid,然后用lower_bound(a+1,a+1+n,mid)来找第一个大于等于mid的数的位置,然后判断前后的和是否一样,和t一样大的数我们不需要考虑,因为他要么被抛弃,要么平分,没有影响
详细看代码吧

代码:

/*
7
3
6
4
4
4
1
2
*/

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
    
    
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=1e5+9;
int a[maxn];
int ch[2*maxn];
int n;
int sum[maxn];
int check(int mid)
{
    
    
	int w=lower_bound(a+1,a+1+n,mid)-a;
	
	int pos1;
	pos1=w-1;
	int pos2=w+ch[mid]-1;
	if((sum[pos1])>=(sum[n]-sum[pos2]))return 1;
	return 0;
}
int main()
{
    
    
	
	cin>>n;
	int tot=0;
	for(int i=1;i<=n;i++)
	{
    
    
		cin>>a[i];
		ch[a[i]]++;
		
	}
	bool f=1;
	for(int i=2;i<=n;i++)
	{
    
    
		if(a[1]!=a[i])
		{
    
    
			f=0;
		} 
	}
	if(f==1)
	{
    
    
		cout<<a[1]<<endl;
		return 0;
		
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
	int l=0,r=2e4+9;
	while(l<r)
	{
    
    
		int mid=(l+r)>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	cout<<l;
}

H On Average They’re Purple

题意:

我们首先规定,如果两个边有公共点,且两边是不一样的颜色,如果从一个边走到另一个边,我们称之为“颜色变换”
给你一个图,n个点,m条边,A要从1走到n点,B要给m个边染色,B想要A尽可能走颜色变换,A会尽可能少走“颜色变化”,输出A最少走多少?
(一共就两个颜色)

题解:

因为一共就两个颜色,所以B想要A走更多的颜色变换就是两个颜色交替走,A要走最少其实就是走最短路,B给最短路染色,所以答案就是1到n的最短路减1
直接套最短路模板

代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 300005
#define maxm 500005
#define INF  1234567890
inline int read()
{
    
    
    int x=0,k=1; char c=getchar();
    while(c<'0'||c>'9'){
    
    if(c=='-')k=-1;c=getchar();}
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*k;
}
struct Edge
{
    
    
    int u,v,w,next;
}e[maxm];
int head[maxn],cnt,n,m,s,vis[maxn],dis[maxn],pre[maxn];
struct node
{
    
    
    int w,now;
    inline bool operator <(const node &x)const
    //重载运算符把最小的元素放在堆顶(大根堆)
    {
    
    
        return w>x.w;//这里注意符号要为'>'
    }
};
priority_queue<node>q;
//优先队列,其实这里一般使用一个pair,但为了方便理解所以用的结构体
inline void add(int u,int v,int w)
{
    
    
    e[++cnt].u=u;
    //这句话对于此题不需要,但在缩点之类的问题还是有用的
    e[cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    //存储该点的下一条边
    head[u]=cnt;
    //更新目前该点的最后一条边(就是这一条边)
}
//链式前向星加边

void print(int x)
{
    
    
	if(pre[x]==0)return ;
	print(pre[x]);
	cout<<"-> "<<x;
}
void dijkstra()
{
    
    
    for(int i=1;i<=n;i++)
    {
    
    
        dis[i]=INF;
    }
    dis[s]=0;
    //赋初值
    q.push((node){
    
    0,s});
    while(!q.empty())
    //堆为空即为所有点都更新
    {
    
    
        node x=q.top();
        q.pop();
        int u=x.now;
        //记录堆顶(堆内最小的边)并将其弹出
        if(vis[u]) continue; 
        //没有遍历过才需要遍历
        vis[u]=1;
        for(int i=head[u];i;i=e[i].next)
        //搜索堆顶所有连边
        {
    
    
            int v=e[i].v;
            if(dis[v]>dis[u]+e[i].w)
            {
    
    
                dis[v]=dis[u]+e[i].w;
                pre[v]=u;
                //松弛操作
                q.push((node){
    
    dis[v],v});
                //把新遍历到的点加入堆中
            }
        }
    }
}
int main()
{
    
    
    n=read(),m=read(),s=1;
    for(int i=1,x,y,z;i<=m;i++)
    {
    
    
        x=read(),y=read(),z=1;
        add(x,y,z);
        add(y,x,z);
    }
    dijkstra();
	printf("%d ",dis[n]-1);
 //       print(i);
  //      cout<<endl;
    return 0;
}

J This Ain’t Your Grandpa’s Checkerboard

题意:

一个合法的图满足以下要求:
每行黑块一样多
每列黑块一样多
没有连续的三个黑块

题解:

模拟,照着题意模拟即可

代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
    
    
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}//
const int maxn=40;
char a[maxn][maxn];
int main()
{
    
    
	int n;
	cin>>n;
	char ch=getchar();
	for(int i=1;i<=n;i++)
	{
    
    	
		for(int j=1;j<=n;j++){
    
    
			cin>>a[i][j];
		}
		ch=getchar();
	}
	bool f=1;
	int sum=0;
	int sum1=0;
	for(int i=1;i<=n;i++)
	{
    
    
		sum1=0;
		for(int j=1;j<=n;j++)
		{
    
    
			if(a[i][j]==a[i][j-1]&&a[i][j]==a[i][j-2]&&j>=3)
			{
    
    
				f=0;
				break;
			}
			if(i==1)
			{
    
    
				if(a[i][j]=='W')sum++;
			}
			else 
			{
    
    
				if(a[i][j]=='W')sum1++;
			}
		}
		if(sum1!=sum&&i!=1)
		{
    
    
			f=0;
			break;
		}
	}
	if(f==0)
	{
    
    
		cout<<0<<endl;
		return 0;
	} 
	sum=0;
	for(int i=1;i<=n;i++)
	{
    
    
		sum1=0;
		for(int j=1;j<=n;j++)
		{
    
    
			if(a[j][i]==a[j-1][i]&&a[j][i]==a[j-2][i]&&j>=3)
			{
    
    
				f=0;
				break;
			}
			if(i==1)
			{
    
    
				if(a[j][i]=='W')sum++;
			}
			else 
			{
    
    
				if(a[j][i]=='W')sum1++;
			}
		}
		if(sum1!=sum&&i!=1)
		{
    
    
			f=0;
			break;
		}
	}
	if(f==0)
	{
    
    
		cout<<0<<endl;
		return 0;
	} 
	cout<<1<<endl;
}

猜你喜欢

转载自blog.csdn.net/qq_35975367/article/details/115284500