文章目录
题号 | 题目 | 通过率 |
---|---|---|
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;
}