sgu 193 Chinese Girls' Amusement

题意:1号开始,一次加k再%n运算,再到1时已经经过了所有的点,问最大的K(k>=n/2)。

1.如果n是奇数,n与n/2互质。

(1)如果n是质数,结论显然成立

(2)否则,n分解为质数乘积。假设n%3==0,那么n=3,9,15,21......(因为前提是奇数),n/2=1,4,7,10。观察n/2%3显然不为0。因此如果n%3==0,n/2%3!=0,如果n%5==0,n/2%5!=0。

2.如果n是偶数。n/2-1或n/2-2与n互质。

(1)如果n/2为奇,n/2-2与n互质。

n/2为奇,那么n的质数因子除了2,也是n/2的质数因子。比如,30=2*3*5,15=3*5,都有质因子3和5.而n/2-1和n不互质。n/2-2和n/2互质,即n/2-2不整除n/2的所有因子。n/2-2又不整除2。因此n/2-2不整除n的所有因子。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#define mkp make_pair
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const int SZ=20010,INF=0x7FFFFFFF;
char str[SZ],res[SZ];

int Subtraction(char num1[], char num2[], int sum[])
{
    int i, j, len, blag;
    char *temp;
    int n2[SZ] = {0};
    int len1 = strlen(num1); // ????num1???,?????? 
    int len2 = strlen(num2); // ????num2???,??????
    
    // ??????????????? 
    blag = 0; // ?0????????,?1???????? 
    if(len1 < len2) // ???????????
    {
        blag = 1; // ???????
        // ?????,???? 
        temp = num1;
        num1 = num2;
        num2 = temp;
        len = len1;
        len1 = len2;
        len2 = len;
    }
    else if(len1 ==len2) // ???????????????
    {  
        // ?????? 
        for(i = 0; i < len1; i++)
        {
            if(num1[i] == num2[i])
                continue;
            if(num1[i] > num2[i])
            {
                blag = 0; // ??????? 
                break;
            } 
            else
            {
                blag = 1; // ??????? 
                // ?????,???? 
                temp = num1;
                num1 = num2;
                num2 = temp;
                break;
            } 
        } 
    }
    len = len1>len2 ? len1 : len2; // ???????
    //?num1???????????????????????sum?,?????,????
    for (i = len1-1, j = 0; i >= 0; i--, j++) 
        sum[j] = num1[i] - '0';
    // ?????? 
    for (i = len2-1, j = 0; i >= 0; i--, j++)
        n2[j] = num2[i] - '0';
    // ??????? 
    for (i = 0; i <= len; i++)
    {
        sum[i] = sum[i] - n2[i]; // ?????????? 
        if (sum[i] < 0)   // ??????? 
        {    // ?? 
            sum[i] += 10;
            sum[i+1]--;
        }
    }
    // ?????? 
    for (i = len1-1; i>=0 && sum[i] == 0; i--)
        ;
    len = i+1;
    if(blag==1)
    {
        sum[len] = -1;  // ???????-1???? 
        len++;
    }
    return len;   // ??????? 
}

int SubStract(int *p1, int len1, int *p2, int len2)
{
    int i;
    if(len1 < len2)
        return -1;
    if(len1 == len2 )
    {                        // ??p1 > p2
        for(i = len1-1; i >= 0; i--)
        {
            if(p1[i] > p2[i])   // ??,?????,????
                break;
            else if(p1[i] < p2[i]) // ????-1
                return -1;
        }
    }
    for(i = 0; i <= len1-1; i++)  // ????????
    {
        p1[i] -= p2[i];         // ?? 
        if(p1[i] < 0)           // ???????
        {   // ?? 
            p1[i] += 10;
            p1[i+1]--;
        }
    }
    for(i = len1-1; i >= 0; i--)  // ????????
    {
        if( p1[i] )             //????????0
            return (i+1);       //???????
    } 
    return 0;                   //?????????0
}


/*
  ????---???????? 
  num1 ???
  num2 ?? 
  sum  ?,???????,?:num1/num2=sum
  ????sum?????,????? 
*/ 
int Division(char num1[], char num2[], char sum[])
{
    int k, i, j;
    int len1, len2, len=0;     //????
    int dValue;                //???????
    int nTemp;                 //Subtract?????
    int num_a[SZ] = {0};      //???
    int num_b[SZ] = {0};      //??
    int num_c[SZ] = {0};      //? 

    len1 = strlen(num1);       //???????
    len2 = strlen(num2);
    
    //???????????,??????????? 
    for( j = 0, i = len1-1; i >= 0; j++, i-- )
        num_a[j] = num1[i] - '0';
    for( j = 0, i = len2-1; i >= 0; j++, i-- )
        num_b[j] = num2[i] - '0';

    if( len1 < len2 )          //?????????,????-1,?????0
    {
        return -1;
    }
    dValue = len1 - len2;      //????
    for (i = len1-1; i >= 0; i--)    //?????,????????????
    {
        if (i >= dValue)
            num_b[i] = num_b[i-dValue];
        else                         //???0
            num_b[i] = 0;
    }
    len2 = len1;
    for(j = 0; j <= dValue; j++ )    //????,??????????,???
    {
        while((nTemp = SubStract(num_a, len1, num_b+j, len2-j)) >= 0)
        {
            len1 = nTemp;            //????
            num_c[dValue-j]++;       //??????,???????1
        }
    }
    // ??????,?????sum????? 
    for(i = SZ-1; num_c[i] == 0 && i >= 0; i-- );  //????0,?????? 
    if(i >= 0)
        len = i + 1; // ???? 
    for(j = 0; i >= 0; i--, j++)     // ??????sum??? 
        sum[j] = num_c[i] + '0';
    sum[j] = '\0';   // sum???????0 
    return len;      // ?????? 
} 


int main()
{
    //std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin);
    lon casenum;
    //cin>>casenum;
    //for(lon time=1;time<=casenum;++time)
    {
        cin>>str;
        int slen=strlen(str);
        char two[]="2";
        int rlen=Division(str,two,res);
        //cout<<res<<endl;
        if((str[slen-1]-'0')&1)cout<<res<<endl;
        else if((res[rlen-1]-'0')&1)
        {
            
            int r[SZ];
            //int sz=1000;
            int sz=Subtraction(res,two,r);
            for(int i=sz-1;i>=0;--i)
            {
                cout<<r[i];
            }cout<<endl;
        }
        else
        {
            two[0]='1';
            //cout<<res<<endl;
            //two[0]='1';
            int r[SZ];
            int sz=Subtraction(res,two,r);
            for(int i=sz-1;i>=0;--i)
            {
                cout<<r[i];
            }cout<<endl;
        }
    }
    return 0;
}

(2)n/2为偶,n/2-1与n互质。

n/2为偶,那么n的质数因子也是n/2的质数因子。比如12=2^2*3,6=2*3,都有质因子2和3.而n/2-1和n/2没有共同质因子。

猜你喜欢

转载自www.cnblogs.com/gaudar/p/9805242.html
sgu