牛客小白月赛64

https://ac.nowcoder.com/acm/contest/49244
小杜要迟到了!

分析:

比较(n-1)a和 (n+k-2)b的大小,按要求输出结果即可。 时间复杂度O(1)

#include<bits/stdc++.h>
#define ll long long
#define L(i,j,k) for(ll i=(j);i<=(k);++i)
#define R(i,j,k) for(ll i=(j);i>=(k);--i)
#define inf 2e9
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define MS(i,j) memset(i,j,sizeof (i))
const int N=1e6+10,M=10;
const int mod=998244353,mmod=mod-1;
const double pi=acos(-1),eps=1e-8;
using namespace std;

int m,n,t,x,y,z,l,r,u,v,k,p,pp,nx,ny,nz,ansx,ansy,mn,mx;
int a,b;
int rt,op,lim,pos,key,block;
int cnt,tot,num,sum,ans;

void solve(){
    scanf("%d%d%d%d",&n,&k,&a,&b);
    ll x=1ll*(n-1)*a;
    ll y=1ll*(n+k-2)*b;
    if(x>y)puts("1");
    else if(x<y)puts("2");
    else puts("0");
}

int main(){
    int Case=1;
    //scanf("%d",&Case);
    while(Case--)solve();
}

小杜捕鱼

分析:
考虑哪个位置距离所有鱼的位置的最大值最大,即矩形鱼塘的四个角落。

分别计算撒网中心落在(1,1),(1,m),(n,1),(n,m)时,与所有鱼的曼哈顿距离的最大值。

四种结果再取一个最大值。 时间复杂度O(nm)

#include<bits/stdc++.h>
#define ll long long
#define L(i,j,k) for(int i=(j);i<=(k);++i)
#define R(i,j,k) for(int i=(j);i>=(k);--i)
#define inf 2e9
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define MS(i,j) memset(i,j,sizeof (i))
const int N=1e3+10,M=10;
const int mod=998244353,mmod=mod-1;
const double pi=acos(-1),eps=1e-8;
using namespace std;

int m,n,t,x,y,z,l,r,u,v,k,p,pp,nx,ny,nz,ansx,ansy,mn,mx;
int a,b;
int rt,op,lim,pos,key,block;
int cnt,tot,num,sum,ans;
char s[N][N];

void solve(){
    scanf("%d%d",&n,&m);
    ans=0;
    L(i,1,n)scanf("%s",s[i]+1);
    L(i,1,n)L(j,1,m)if(s[i][j]=='#'){
        ans=max(ans,i-1+j-1);
        ans=max(ans,i-1+m-j);
        ans=max(ans,n-i+j-1);
        ans=max(ans,n-i+m-j);
    }
    printf("%d\n",ans);
}

int main(){
    int Case=1;
    //scanf("%d",&Case);
    while(Case--)solve();
}

Karashi的生日蛋糕

分析:

#include<bits/stdc++.h>
#define ll long long
#define L(i,j,k) for(int i=(j);i<=(k);++i)
#define R(i,j,k) for(int i=(j);i>=(k);--i)
#define inf 2e9
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define MS(i,j) memset(i,j,sizeof (i))
const int N=1e3+10,M=10;
const int mod=998244353,mmod=mod-1;
const double pi=acos(-1),eps=1e-8;
using namespace std;

int m,n,t,x,y,z,l,r,u,v,k,p,pp,nx,ny,nz,ansx,ansy,mn,mx;
int rt,op,lim,pos,key,block;
int cnt,tot,num,sum,ans;

void solve(){
    scanf("%d%d",&n,&k);
    vector<vector<int> >sv(k+2,vector<int>(n+2,0));
    p=1;
    L(j,1,n)L(i,1,j%k){
        sv[p][j]=1;
        p++;
        if(p>k)p-=k;
    }
    L(i,1,k){
        L(j,1,n){
            printf("%d ",sv[i][j]+j/k);
        }
        printf("\n");
    }
}

int main(){
    int Case=1;
    //scanf("%d",&Case);
    while(Case--)solve();
}

Karashi的树 I

分析:

先考虑叶子节点上的值一定是最小的 我们一定能进行两次交换使得最小值先到根节点 再到叶子结点

同理处理完所有叶子结点 就产生新一层的叶子节点 所以我们一定能通过交换操作使得满足最大

考虑每个点对答案的贡献 为sz[u]×a[u] 其中sz[u]为u子树的大小

我们对所有的a排序 sz排序 相应地相乘即可满足最大

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=3e5+5;
int n;
ll a[maxn],num[maxn],ans;
vector<int>Q[maxn];
void solve();
void dfs(int);
int main(){
	int T;T=1;
	while(T--)solve();
     return 0;
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	for(int i=2,x;i<=n;i++)scanf("%d",&x),Q[x].push_back(i);
	dfs(1);
	sort(a+1,a+1+n);
	sort(num+1,num+1+n);
	for(int i=1;i<=n;i++)
	ans+=a[i]*num[i];
	cout<<ans;
}
void dfs(int u){
	num[u]=1;
	for(int i=0;i<Q[u].size();i++){
		int to=Q[u][i];
		dfs(to);
		num[u]+=num[to];
	}
}

Karashi的数组

分析:

#include<bits/stdc++.h>
#define ll long long
#define L(i,j,k) for(int i=(j);i<=(k);++i)
#define R(i,j,k) for(int i=(j);i>=(k);--i)
#define inf 2e9
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define MS(i,j) memset(i,j,sizeof (i))
const int N=1e6+10,M=10;
const int mod=998244353,mmod=mod-1;
const double pi=acos(-1),eps=1e-8;
using namespace std;

int m,n,t,x,y,z,l,r,u,v,k,p,q,pp,nx,ny,nz,ansx,ansy,mn,mx;
int rt,op,lim,pos,key,block;
int cnt,tot,len,num,sum,ans;
int a[N];

void solve(){
    scanf("%d%d%d",&n,&m,&len);
    L(i,1,n)scanf("%d",&a[i]);
    ans=0;
    L(k,1,n-len-1){
        if(a[k]==0||a[k+len+1]==0)ans++;
    }
    while(m--){
        scanf("%d%d",&pos,&x);
        l=pos-len-1,r=pos;
        if(1<=l&&l<=n-len-1&&a[l]!=0){
            if(a[pos]==0)ans--;
            if(x==0)ans++;
        }
        if(1<=r&&r<=n-len-1&&a[r+len+1]!=0){
            if(a[pos]==0)ans--;
            if(x==0)ans++;
        }
        printf("%d\n",ans);
        a[pos]=x;
    }
}

int main(){
    int Case=1;
    //scanf("%d",&Case);
    while(Case--)solve();
}

小杜跑酷

分析:

考虑到n有1e9 我们只用考虑机关 首先对每个机关所占的位置进行离散化

离散化之后就顺序转移即可

考虑位置<i,j> 如果<i,j-1>为非机关 dp[i][j]+=dp[i][j-1] 如果为机关 就按照题意相应转移即可

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int mod=998244353;
const int maxn=3e6+5;
void solve();
int n,m,cnt,len;
int b[maxn],vis[3][maxn];
ll dp[3][maxn];
struct node{
	int x,y;
}a[maxn];
int find(int yy){
	return lower_bound(b+1,b+1+len,yy)-b;
}
int main(){
	int T;T=1;
	while(T--)solve();
     return 0;
}
void solve(){
	cin>>n>>m;
	for(int i=1;i<=m;i++)
    scanf("%d%d",&a[i].x,&a[i].y),b[++cnt]=a[i].y,b[++cnt]=a[i].y+1,b[++cnt]=min(n,a[i].y+2),a[i].x--;
	sort(b+1,b+1+cnt);
    len=unique(b+1,b+1+cnt)-b-1;
    for(int i=1;i<=m;i++)
    a[i].y=find(a[i].y),vis[a[i].x][a[i].y]=1;
    dp[0][1]=1;
    for(int j=1;j<=len;j++){
    	for(int i=0;i<=2;i++){
    		if(!vis[i][j-1])
    		dp[i][j]=(dp[i][j]+dp[i][j-1])%mod;
			if(vis[i][j]){
    			dp[max(0,i-1)][j+1]=(dp[i][j]+dp[max(0,i-1)][j+1])%mod;
    			dp[i][min(len,j+2)]=(dp[i][j]+dp[i][min(len,j+2)])%mod;
    			dp[min(2,i+1)][j+1]=(dp[i][j]+dp[min(2,i+1)][j+1])%mod;
			}
    		
		}
	}
	cout<<dp[0][len]<<endl<<dp[1][len]<<endl<<dp[2][len];
}

posted @ 2023-01-12 18:49  wzx_believer  阅读(48)  评论(0)    收藏  举报