首先,没看懂题目之前是自闭的。
看懂题目之后基本都能想出正解。
第一题:
A和B两个人,给出他们俩的坐标,如果A和B在同一行,那么A受到一点伤害,A可以放子弹,如果B碰到子弹,B受到一点伤害。
两种操作,所有子弹向上,下,左,右移动;或者B向上,下,左,右移动。
暴力即可,注意是在平面直角坐标系上。
#include
#include
#include
#include
using namespace std;
int Case;
int n,m,q;
int ax,ay,bx,by;
int sx,sy;
char s[10];
struct node{
int x,y;
}p[1010];
bool tf[110][110];
int ans1,ans2;
int main(){
scanf("%d",&Case);
int t=0;
int x,y;
scanf("%d %d",&n,&m);
scanf("%d %d",&ax,&ay);
scanf("%d %d",&bx,&by);
sx=bx,sy=by;
ans1=ans2=0;
scanf("%d",&q);
memset(tf,false,sizeof(tf));
for(int i=1;i<=q;i++){
if(ax==bx) ans1++;
if(tf[bx][by]) ans2++;
scanf("%s",s);
if(s[0]=='D'){
scanf("%d %d",&x,&y);
tf[x][y]=false;
}
else if(s[0]=='I'){
scanf("%d %d",&x,&y);
tf[x][y]=true;
}
else if(s[0]=='M' && s[1]=='A'){
t=0;
scanf("%s",s);
for(int a=1;a<=n;a++)
for(int b=1;b<=m;b++)
if(tf[a][b]) p[++t]=(node){a,b};
memset(tf,false,sizeof(tf));
if(s[0]=='U') for(int a=1;a<=t;a++) p[a].y++;
if(s[0]=='D') for(int a=1;a<=t;a++) p[a].y--;
if(s[0]=='L') for(int a=1;a<=t;a++) p[a].x--;
if(s[0]=='R') for(int a=1;a<=t;a++) p[a].x++;
for(int a=1;a<=t;a++) if(p[a].x>=1 && p[a].x<=n && p[a].y>=1 && p[a].y<=m) tf[p[a].x][p[a].y]=true;
}
else if(s[0]=='M' && s[1]=='B'){
scanf("%s",s);
if(s[0]=='U') by++;
if(s[0]=='D') by--;
if(s[0]=='L') bx--;
if(s[0]=='R') bx++;
if(bx>n || bx<1 || by>m || by<1) bx=sx,by=sy;
}
}
printf("%d\n%d\n",ans2,ans1);
}
第二题:
n个点,有k个点是关键点,构造全排列,对于每个排列的费用是排列中相邻两个点路径的距离之和。
求费用的期望。
从a到b的距离会被算那么多次,所以我们对于每个点求一遍这个点到其他点的距离和,加起来乘上即可。
最后除以,其实就相当于除以一个k。
#include
#include
#include
#include
using namespace std;
struct edge{
int y,next,c;
}s[2000010];
int first[1000010],len=0;
int t;
int n,k;
long long tot[1000010];
long long in[1000010],out[1000010];
int p[1000010];
long long mod=998244353;
void ins(int x,int y,int c){
len++;
s[len]=(edge){y,first[x],c};first[x]=len;
}
void dfs_1(int x,int fa){
for(int i=first[x];i!=0;i=s[i].next){
int y=s[i].y;
if(y==fa) continue;
dfs_1(y,x);
tot[x]+=tot[y];
in[x]+=in[y]+tot[y]*s[i].c;
}
}
void dfs_2(int x,int fa){
for(int i=first[x];i!=0;i=s[i].next){
int y=s[i].y;
if(y==fa) continue;
out[y]=out[x]+in[x]-(in[y]+tot[y]*s[i].c)+(k-tot[y])*s[i].c;
dfs_2(y,x);
}
}
long long ksm(long long x,long long t){
long long tot=1;
while(t){
if(t%2) (tot*=x)%=mod;
(x*=x)%=mod;
t/=2;
}
return tot;
}
int main(){
scanf("%d",&t);
scanf("%d",&n);
int x,y,c;
for(int i=1;i<=n-1;i++){
scanf("%d %d %d",&x,&y,&c);
ins(x,y,c);ins(y,x,c);
}
scanf("%d",&k);
for(int i=1;i<=k;i++){
scanf("%d",&x);
p[i]=x;
tot[x]=1;
}
dfs_1(1,0);
dfs_2(1,0);
long long ans=0;
for(int i=1;i<=k;i++) (ans+=in[p[i]]+out[p[i]])%=mod;
printf("%lld",ans*ksm(k,mod-2)%mod);
}
第三题:
每个点有一种颜色,共有四种颜色,A能到B当且仅当A到B的路径上每一个周期(4个为一周期)颜色不同。
求一个点,使得这个点到k个点的距离最小。
状态压缩+bfs即可。
#include
#include
#include
#include
#include
using namespace std;
struct edge{
int y,next;
}s[400010];
int first[50010],len=0;
int type[50010];
char ch[50010];
int tf[50010][16];
int mmax[50010],tot[50010];
int T;
int n,m,k;
int p[15];
struct node{
int x,S,t;
};
queue f;
void ins(int x,int y){
len++;
s[len]=(edge){y,first[x]};first[x]=len;
}
void bfs(int st){
memset(tf,63,sizeof(tf));
f.push((node){st,1<
总的来说,这次比赛挺简单的,第一题和第三题都打了出来,第二题思维深度也不高。
注意细节吧。