codeforces 755 d PolandBall and Polygon(找规律)

106 篇文章 0 订阅
51 篇文章 0 订阅

题意:

给一个凸n边形,给定一个数字k,保证gcd(n,k)等于1,顺时针每隔k个点连一条线,问每连一条线凸多边形被划成多少块。


思路:

容易得出,每次画一条线,它所多划分出来的块数就是它穿过的线数加一,而它所穿过的线的数量就是这条线连接的两个点之间,已经有线连接的点的数量乘2.例如


在2和4之间连 一条线,2和4之间3已经被连接了,所以2和4这条线穿过的线的数量就是1*2。但是有一种情况很特殊,就是当两个点之间包含了始发点的时候,例如


在2和5之间连一条线的话,它们中间就有一个始发点1,虽然1有线相连,但是只有一条线和它相连,可以确定这种情况只会发生在始发点这一个点上,也就是其他点一旦有线相连就一定是两条线相连,所以这个情况特判一下就好。

明确了点和线之间的关系后,我们就可以把问题转化为如何求点了。那么两个点之间会有几个点已经有线相连呢?很简单,如果连线的操作已经超过 了1圈,那么你连的两个点之间必有且只有一个点是有连线的,n圈就是n个点,所以得解。

具体记录圈数的做法,一开始我是想用操作次数i/k来判断圈数的,但是这样总是容易出岔子,所以就用了一个变量j来记录当前连接到哪个点了,每次加k模拟出来,这样最简单了。

trick:

1.最后这题我忘了写k>n/2的情况wa了,这种情况就不能用上面这种做法了,但是其实k>n/2的时候,就相当于逆时针每隔n-k个点进行添加,所以直接让k=n-k即可。

2.答案要用longlong

代码:

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n, k;
    scanf("%d%d", &n, &k);
    if(k>n/2)k=n-k;//k>n/2时转换一下
    long long ans=1;
    int j=1, i, circle=0;
    for(i=0; i<n; i++)
    {
        if(j+k>n+1){ans+=circle*2+2;j=(j+k)%n;if(j==0)j=n;circle++;}//当要跨越始发点时,也是新的一圈开始的时候,所以比上一圈普通情况加的块数多一即可,圈数要更新
        else {ans+=circle*2+1; j=(j+k)%n; if(j==0)j=n; }

        printf(i==n-1?"%lld\n":"%lld ", ans);
//        printf("%d %d\n", j, circle);
    }

    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值