2019-计蒜客信息学普及组赛前模拟 #1 A,B,C,D

下午打完训练赛,又不想补题,正好看见计蒜课有一场普及组和提高组的模拟赛,就顺便打一下。

为了放松心情,就打了普及组的(本来就被打自闭了,为了开心肯定挑简单题啊

Contest:https://www.jisuanke.com/contest/4578?view=challenges

A-爬山(签到)

题目链接:https://nanti.jisuanke.com/t/41957

题目大意:中文题。

思路:按着模拟就好了,简单签到提。

ACCode:

int A[MAXN];
int n;

int main(){
	scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&A[i]);
	int ans=0;
    for(int i=1;i<n;++i){
		ans=max(ans,abs(A[i+1]-A[i]));
    }printf("%d\n",ans);
}

B-纸片(数学签到)

题目链接:https://nanti.jisuanke.com/t/41958

题目大意:中文题。

思路:猛一看确实没什么思路,但是突然发现组成的数可以拆分成Ans=l*10^a+(l+1)*10^b+....+(r-1)*10+r;

然后就显而易见了。对9取模之后就是\sum_{i=l}^{r} i,前n项和公式就好了,注意可能会爆ll,所以用__int128或者取一下逆元都行。

ACCode:

ll Inv(ll a,ll b){
	ll res=1;
    while(b){
		if(b&1) res=res*a%MOD;
        a=a*a%MOD;
        b>>=1;
    }return res;
}
int main(){
	int T;scanf("%d",&T);
    while(T--){
        ll l,r;scanf("%lld%lld",&l,&r);
        ll ans=((l+r)%MOD)*((r-l+1)%MOD)*Inv(2,MOD-2);
        if(ans%MOD==0) printf("Y\n");
        else printf("N\n");
    }
}

C-颜色(简单搜索)

题目链接:https://nanti.jisuanke.com/t/41959

题目大意:中文题

思路:由于数据范围比较小,给的时间又很充裕,就随便搜了,开个map记录一下数量,最后统计答案就好了。

ACCode:

int Fx[5]={0,0,0,1,-1},Fy[5]={0,1,-1,0,0};
map<int,int> Cnt;
int A[MAXN][MAXN],Vis[MAXN][MAXN];
int n,m;

int Check(PII u){
    if(A[u.first][u.second]==0||Vis[u.first][u.second]) return 0;
    if(u.first<1||u.first>n||u.second<1||u.second>m) return 0;
    return 1;
}
int BFS(PII str){
	Cnt.clear();
    queue<PII> que;que.push(str);
    Cnt[A[str.first][str.second]]=1;
    Vis[str.first][str.second]=1;
    while(que.size()){
		PII u=que.front();que.pop();
        for(int i=1;i<=4;++i){
            PII v=make_pair(u.first+Fx[i],u.second+Fy[i]);
            if(Check(v)){//查看是否符合要求
                Vis[v.first][v.second]=1;//以后不再访问
                Cnt[A[v.first][v.second]]=1;
                que.push(v);
            }
        }
    }return Cnt.size();
}
int main(){
	scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j) scanf("%d",&A[i][j]);
    }
    int ans=0;
    for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
            if(Vis[i][j]||A[i][j]==0) continue;
			ans=max(ans,BFS(make_pair(i,j)));
        }
    }printf("%d\n",ans);
}

D-祖先(思维)

题目链接:https://nanti.jisuanke.com/t/41960

题目大意:中文题。

思路:其实这道题还真不知道具体什么算法,就是找找规律,然后优化一下常数,(我一开始还以为算法问题。。结果是常数。。

用快读和向前星。

看样例可以发现,(a,b)和(b,a)不算一个。所以很明显有一个式子:

Ans[u]=Siz[u]+\sum_{u->v}((Siz[u]-Siz[v])*Siz[v]).

然后合并一下就可以转化成:

Ans[u]=Siz[u]*Siz[u]-\sum_{_u->v}Siz[v]*Siz[v]

与处理一下直接输出就好了。(一开始习惯性写vector和scanf,T掉了。。)

ACCode:

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand((unsigned)time(NULL));rand();
      
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
 
#define ll long long
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
      
const int MAXN=1e6+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)

struct Edge1{
	int v,nxt;
	Edge1(int _v=0,int _nxt=0){
		v=_v;nxt=_nxt;
	}
};
Edge1 Edge[MAXN*2];
int Head[MAXN],Ecnt;
int Siz[MAXN],Dep[MAXN],Fa[MAXN];
ll Ans[MAXN];
//vector<int> G[MAXN];
int n,m,rt;

int Read(){
	char ch=getchar();
	int res=0;
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9'){
		res=res*10+ch-'0';ch=getchar();
	}return res;
}
char Num[100];
void Print(ll x){
	int len=0;
	while(x){
		ll tmp=x%10;
		Num[++len]=tmp+'0';
		x/=10;
	}
	for(int i=len;i>=1;--i) putchar(Num[i]);puts("");
}
void AddEdge(int u,int v){
	Edge[Ecnt]=Edge1(v,Head[u]);
	Head[u]=Ecnt++;
}
int DFS(int u,int fa=-1,int dep=0){
	Siz[u]=1;Dep[u]=dep;Fa[u]=fa;
	for(int i=Head[u];i+1;i=Edge[i].nxt){
		int v=Edge[i].v;
		if(v==fa) continue ;
		Siz[u]+=DFS(v,u,dep+1);
	}return Siz[u];
//	for(int i=0;i<G[u].size();++i){
//		int v=G[u][i];
//		if(v==fa) continue;
//		Siz[u]+=DFS(v,u,dep+1);
//	}return Siz[u];
}
int main(){
	//scanf("%d%d%d",&n,&m,&rt);
	n=Read();m=Read();rt=Read();
	clean(Head,-1);Ecnt=0;
	for(int i=2;i<=n;++i){
		int u,v;u=Read();v=Read();//scanf("%d%d",&u,&v);
		AddEdge(u,v);AddEdge(v,u);
		//G[u].push_back(v);G[v].push_back(u); 
	}
	DFS(rt);
//	for(int i=1;i<=n;++i) printf("i=%d siz=%d\n",i,Siz[i]);
	for(int i=1;i<=n;++i){
		ll res=0;
		Ans[i]=1ll*Siz[i]*Siz[i]%MOD;
		for(int j=Head[i];j+1;j=Edge[j].nxt){
			int v=Edge[j].v;
			if(Fa[i]==v) continue ;
			res=(res+1ll*Siz[v]*Siz[v])%MOD;
		}
//		for(int j=0;j<G[i].size();++j){
//			int v=G[i][j];
//			if(Fa[i]==v) continue ;
//			res=(res+1ll*Siz[v]*Siz[v]%MOD)%MOD;
//		}
		Ans[i]=(Ans[i]-res+MOD)%MOD;
	}
	for(int i=1;i<=m;++i){
		int x;x=Read();//scanf("%d",&x);
		Print(Ans[x]);//printf("%lld\n",Ans[x]);
	}
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值