题解
今天这个题没一个正常的
早上睡过头了,起来肝还痛着
第一题——Jingle
【题目描述】
- 给出若干字符W/H/Q/E/S/T/X分别代表节拍大小1、1/2、1/4、1/8、1/16、1/32、1/64,用/分割为单元,求有多少个单位的节拍刚好为1。
- 水题,不讲!
#include <bits/stdc++.h>
using namespace std;
inline void fff(){
freopen("jingle.in","r",stdin);
freopen("jingle.out","w",stdout);
}
inline int read(){
int x=0,m=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') m=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return m*x;
}
const int N=1e6+10;
int val[200];
char ch[N];
int n;
int main(){
// fff();
cin>>ch;
n=strlen(ch);
ch[n++]='/';
val['W']=64,val['H']=32,val['Q']=16;
val['E']=8,val['S']=4,val['T']=2,val['X']=1;
int sum=0,ans=0;
for(int i=0;i<n;i++){
if(ch[i]=='/'){
if(sum==64) ans++;
sum=0;
}else sum+=val[ch[i]];
}
cout<<ans;
}
第二题——Perfect
【题目描述】
- 给定M个二元组 ( A i , B i ) (A_i, B_i) (Ai,Bi),求 X 1 X_1 X1, …, X N X_N XN满足:对于任意 ( A i , B i ) (A_i, B_i) (Ai,Bi),有 ∣ X A i − X B i ∣ = 1 |X_{A_i} - X_{B_i}| = 1 ∣XAi−XBi∣=1成立。
- 有解输出YES和合法解,没有输出NO
这道题我刚开始还没想出来- 其实你会发现好像两个点相邻的只有相差为1,那么数值就只有1和0两个解了。然后就发现这个是二分图
- 但其实不需要当二分图做。数值是唯一的就当差分约束就可以了。
#include <bits/stdc++.h>
using namespace std;
inline void fff(){
freopen("perfect.in","r",stdin);
freopen("perfect.out","w",stdout);
}
inline int read(){
int x=0,m=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') m=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return m*x;
}
const int N=10010;
const int M=110000;
const int INF=0x3f3f3f;
int n,m;
struct node{
int x,y;
}a[M];
int ans[N];
int main(){
// fff();
n=read(),m=read();
for(int i=1;i<=m;i++){
int u,v;
u=read(),v=read();
a[i].x=u,a[i].y=v;
}
memset(ans,-1,sizeof(ans));
for(int i=1;i<=m;i++){
int u=a[i].x,v=a[i].y;
if((ans[u]==-1)&&(ans[v]!=-1)) swap(u,v);
if(ans[u]==-1){
ans[u]=0;
ans[v]=ans[u]+1;
}else if(ans[v]==-1){
ans[v]=1-ans[u];
}else if(ans[u]!=1-ans[v]){
printf("NO");
return 0;
}
}
printf("YES\n");
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
}
第三题——Pair
【题目描述】
- 给出 N ∗ M N*M N∗M的图,包含X和1-9的数字,分别表示墙和动物。相同的能够联通的动物可以匹配然后消失,消失之后留下空格能够给别的动物做路径。现在要求出最大匹配数的情况下最小的路径长度。
- 这道题其实蛮骚的。就是纯的暴力,第一遍bfs搜状态,套一个bfs搜匹配。
- 然后我就T了一发
- 直接上代码吧。这种题没什么好优化的其实。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=7;
using namespace std;
int c[11][37][2],a[N][N],ans,n,m,ans1;
short int hashh[33554532][2];
int zz[4][2]=
{
{0,1},
{1,0},
{0,-1},
{-1,0}
};
inline int dg1(int b[N][N],int x,int y,int v,int dis[N][N])
{
for(int i=0;i<=3;i++)
{
int xx=zz[i][0]+x,yy=zz[i][1]+y;
if(xx<1 || xx>n || yy<1 || yy>m) continue;
if(b[xx][yy]==11)
{
if(dis[xx][yy]>dis[x][y]+1) dis[xx][yy]=dis[x][y]+1,dg1(b,xx,yy,v,dis);
}
else
if(b[xx][yy]==v)
{
dis[xx][yy]=min(dis[x][y]+1,dis[xx][yy]);
}
}
}
inline int dg(int b[N][N],int v,int sum)
{
int num=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(b[i][j] && b[i][j]!=11) num+=1<<((i-1)*m+j-1);
}
if(!hashh[num][0])
{
hashh[num][0]=sum;
hashh[num][1]=v;
}
else
{
if(hashh[num][0]>sum) return 0;
if(hashh[num][0]==sum && hashh[num][1]<=v) return 0;
hashh[num][0]=sum;
hashh[num][1]=v;
}
bool q=true;
int dis[N][N],mn;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(b[i][j] && b[i][j]!=11)
{
memset(dis,43,sizeof(dis));
dis[i][j]=0;
dg1(b,i,j,b[i][j],dis);
int g=b[i][j];
mn=maxlongint;
for(int k=1;k<=c[g][0][0]-1;k++)
for(int l=k+1;l<=c[g][0][0];l++)
{
if(dis[c[g][k][0]][c[g][k][1]]>dis[c[g][l][0]][c[g][l][1]])
{
int o=c[g][k][0];
c[g][k][0]=c[g][l][0];
c[g][l][0]=o;
o=c[g][k][1];
c[g][k][1]=c[g][l][1];
c[g][l][1]=o;
}
}
for(int k=1;k<=c[g][0][0];k++)
if(dis[c[g][k][0]][c[g][k][1]]!=dis[0][0] && b[c[g][k][0]][c[g][k][1]]==b[i][j] && (i!=c[g][k][0] || j!=c[g][k][1]))
{
b[i][j]=b[c[g][k][0]][c[g][k][1]]=11;
dg(b,v+dis[c[g][k][0]][c[g][k][1]]-1,sum+1);
q=false;
b[i][j]=b[c[g][k][0]][c[g][k][1]]=g;
}
}
}
if(q)
{
if(sum>ans)
{
ans=sum;
ans1=v;
}
else
if(sum==ans && ans1>v) ans1=v;
return 0;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
char ch=getchar();
while((ch<'0' || ch>'9') && ch!='X') ch=getchar();
if(ch>='0' && ch<='9')
{
a[i][j]=ch-47;
c[ch-47][0][0]++;
c[ch-47][c[ch-47][0][0]][0]=i;
c[ch-47][c[ch-47][0][0]][1]=j;
}
}
ans=0;
ans1=maxlongint;
dg(a,0,0);
printf("%d %d",ans,ans1);
}