cf758C. Unfair Poll

链接

点击跳转

题解

这题太繁了

写之前要想得很清楚,首先特判 n = 1 n=1 n=1

如果 n = ̸ 1 n = \not 1 n≠1
先特判 k &lt; m k&lt;m k<m

考虑完整的周期
然后开始搞,对于第 2 2 2行到第 n − 1 n-1 n1行,被加次数是 k / ( n − 1 ) / m k/(n-1)/m k/(n1)/m
第一行是 k / ( n − 1 ) / m / 2 k/(n-1)/m/2 k/(n1)/m/2,最后一行是 k / ( n − 1 ) / m − k / ( n − 1 ) / m / 2 k/(n-1)/m-k/(n-1)/m/2 k/(n1)/mk/(n1)/m/2

然后把 k k k n ( m − 1 ) n(m-1) n(m1)取模

然后分两种情况模拟

代码

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
    ll c, f(1);
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
    for(;isdigit(c);c=getchar())x=x*10+c-0x30;
    return f*x;
}
ll n, m, k, cnt[200][200], x, y, s[200];
int main()
{
    ll i, j;
    cin>>n>>m>>k>>x>>y;
    if(n==1)
    {
        printf("%lld %lld %lld\n",k/m+!!(k%m),k/m,k/m+(y<=k%m));
        return 0;
    }
    if(k<m)
    {
        printf("1 0 %lld",ll(x==1 and y<=k));
        return 0;
    }
    k-=m;
    s[1]++;
    for(i=2;i<=n-1;i++)s[i]+=k/(n-1)/m;
    s[1] += k/(n-1)/m/2;
    s[n] += k/(n-1)/m/2 + k/(n-1)/m%2;
    rep(i,n)rep(j,m)cnt[i][j]=s[i];
    if((k/(n-1)/m)%2==0)
    {
        k%=(n-1)*m;
        for(i=2;k;i++)
        {
            for(j=1;j<=m and k;j++)
            {
                cnt[i][j]++;
                k--;
            }
        }
    }
    else
    {
        k%=(n-1)*m;
        for(i=n-1;k;i--)
        {
            for(j=1;j<=m and k;j++)
            {
                cnt[i][j]++;
                k--;
            }
        }
    }
    ll mx=0, mn=linf;
    rep(i,n)rep(j,m)mx=max(mx,cnt[i][j]), mn=min(mn,cnt[i][j]);
    printf("%lld %lld %lld",mx,mn,cnt[x][y]);
    return 0;
}

更简单的做法

看了题解,发现可以从周期入手

行号的变化规律如下:
( 1 , 2 , 3 , 4 , . . . . , n , n − 1 , . . . , 3 , 2 ) , ( 1 , 2 , 3 , . . . , n , n − 1 , . . . , 3 , 2 ) , 1 , 2 , 3... (1,2,3,4,....,n,n-1,...,3,2),(1,2,3,...,n,n-1,...,3,2),1,2,3... (1,2,3,4,....,n,n1,...,3,2),(1,2,3,...,n,n1,...,3,2),1,2,3...

然后好写多了

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
    ll c, f(1);
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
    for(;isdigit(c);c=getchar())x=x*10+c-0x30;
    return f*x;
}
ll n, m, cnt[200][200], k, x, y, p[200];
int main()
{
    ll i, j, T;
    cin>>n>>m>>k>>x>>y;
    if(n==1)
    {
        printf("%lld %lld %lld\n",k/m+!!(k%m),k/m,k/m+(y<=k%m));
        return 0;
    }
    T=(2*n-2)*m;
    rep(i,n)rep(j,m)cnt[i][j]+=k/T;
    for(i=2;i<n;i++)rep(j,m)cnt[i][j]+=k/T;
    rep(i,n)p[i]=i;
    rep(i,n-2)p[n+i]=n-i;
    ll res=k%T;
    for(i=1;res;i++)
    {
        for(j=1;j<=m and res;j++)
        {
            cnt[p[i]][j]++;
            res--;
        }
    }
    ll mx=0, mn=linf;
    rep(i,n)rep(j,m)mx=max(mx,cnt[i][j]), mn=min(mn,cnt[i][j]);
    printf("%lld %lld %lld",mx,mn,cnt[x][y]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值