• zoj 2313 Chinese Girls' Amusement(A)


    题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1313


    这题的理论就是当且仅当(a,m)=1  时  a*k+b (1<=k<=m)  遍历mod m的完系  


    一开始的感觉就是暴力  从n/2 开始减 ,直到互素为止,于是直接用java大整数写了:

    import java.math.*;
    import java.util.*;
    import java.io.*;
    public class Main {
    	
    	public static void main(String[] args) throws Exception {
    		
    		
    	    Scanner cin=new Scanner(System.in);
    	    
    	    int size=cin.nextInt();
    	    for(int l=0;l<size;l++)
    	    {	
    	    BigInteger n=cin.nextBigInteger();
    	    BigInteger k=n.divide(new BigInteger("2"));
    	    
    	    while(n.gcd(k).compareTo(BigInteger.ONE)!=0)
    	    {
    	      k=k.subtract(BigInteger.ONE);
    	    }
             
    	    
    	    System.out.println(k);
    	    if(l<size-1)   System.out.println();
    	    }
    	  } 
    	   
    }
    
    

    竟然ac了 ,为啥不会超时?

    理论解释是,当n=2*k+1 时 ,结果就是k,  当n=4*k时 结果就是2*k-1,  当n=4*k+2 时,结果就是2*k-2,  所以答案都离n/2距离很近,当然就不会超时了。

    有了理论的分析 ,用c++也比较简单

    但是还是java代码比较简洁~

    #include<iostream>
    #include<cstring>
    using namespace std;
    
    void jminus(int a [],int n,int b)
    {
      a[n-1]-=b;
      for(int i=n-1;i>0;i--)
      {
         if(a[i]<0)
         {
            a[i]+=10;
            a[i-1]-=1;
         }
      }
    }
    void divide(int a [],int n )
    {
    
    
      for(int i=0;i<n-1;i++)
       {
          if(a[i]%2==0)  a[i]=a[i]/2;
          else
          {
             a[i]=a[i]/2;
             a[i+1]+=10;
          }
    
    
       }
        a[n-1]/=2;
    }
    
    
    int main()
    {
    
      int size=0;
      cin>>size;
      for(int l=0;l<size;l++)
      {
    
      char p[2010];
      cin>>p;
      int n=strlen(p);
      int a[n];
    
      for(int i=0;i<n;i++)
       a[i]=p[i]-'0';
    
      if(a[n-1]%2==1)
      {
          divide(a,n);
        int start=0;
        while(a[start]==0)  start++;
    
        for(int i=start;i<n;i++)
        cout<<a[i];
        cout<<endl;
       }
       else
       {
    
         if(n==1)
         {
            
            int temp=a[0];
            if(temp%4==2)
            {
              divide(a,n);
              jminus(a,n,2);
    
            }
    
            else
            {
                divide(a,n);
                jminus(a,n,1);
            }
         }
    
         else
         {
            int temp=a[n-1]+10*a[n-2];
            if(temp%4==2)
            {
              divide(a,n);
              jminus(a,n,2);
            }
    
            else
            {
                 divide(a,n);
                 jminus(a,n,1);
            }
    
    
         }
    
         int start=0;
        while(a[start]==0)  start++;
    
        for(int i=start;i<n;i++)
        cout<<a[i];
        cout<<endl;
    
       }
    
      if(l<size-1) cout<<endl;
      }
    
    
    }

  • 相关阅读:
    zoj 1610(明天做)
    在C#中ParameterizedThreadStart和ThreadStart区别
    datagridview显示行号
    不允许对64位应用程序进行修改”的解决方法
    SQL查询表和存储过程创建修改日期
    推荐一个代码自动完成的工具AutoCode
    .net中的认证(authentication)与授权(authorization)
    SQL语句使用总结(二)
    C#/WinForm给控件加入hint文字
    sql server 2008 express 安装的时提示“重启计算机失败"
  • 原文地址:https://www.cnblogs.com/814jingqi/p/3217948.html
Copyright © 2020-2023  润新知