zjut 1204 01串排序

01串排序  Time Limit:1000MS  Memory Limit:32768K

Description:

将01串首先按长度排序,长度相同时,按1的个数多少进行排序,1的个数相同时再按ASCII码值排序。

 

Input:

输入数据中含有一些01串,01串的长度不大于256个字符。

Output:

重新排列01串的顺序。使得串按基本描述的方式排序。

Sample Input:

10011111
00001101
1010101
1
0
1100

Sample Output:

0
1
1100
1010101
00001101
10011111




尝试1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[10000][256];

int cmp ( const void *a , const void *b )
{   
 return strcmp((char*)a,(char*)b);
}


int main(int argc, char *argv[])
{   int i,n;
 n=0;
 while ( scanf("%s",s[n])!=EOF && s[n][0]!='#' ) n++; 
  qsort(s,n,sizeof(s[0]),cmp);
    for (i=0; i<n; i++)
     printf("%s\n",s[i]);     
 return 0;
}
View Code

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

char s[10000][256];

 

int cmp ( const void *a , const void *b )

         {         return strcmp((char*)a,(char*)b);      }

 

int main(int argc, char *argv[])

 

{  

           int i,n;  n=0;

 while ( scanf("%s",s[n])!=EOF && s[n][0]!='#' )   n++;

       qsort(s,n,sizeof(s[0]),cmp);    

for (i=0; i<n; i++)   

     printf("%s\n",s[i]);   

   return 0;

}






尝试2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[10000][256];

int cmp ( const void *a , const void *b )
{   
  char *x=(char *)a,*y=(char *)b;
if ( strlen(x)!=strlen(y) ) return  strlen(x)-strlen(y);  
}


int main(int argc, char *argv[])
{   int i,n;
 n=0;
 while ( scanf("%s",s[n])!=EOF && s[n][0]!='#' ) n++; 
  qsort(s,n,sizeof(s[0]),cmp);
    for (i=0; i<n; i++)
     printf("%s\n",s[i]);     
 return 0;
}
View Code

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

char s[10000][256];

int cmp ( const void *a , const void *b )

{    

char *x=(char *)a,*y=(char *)b;

if ( strlen(x)!=strlen(y) )                  return  strlen(x)-strlen(y);        

     }

 

int main(int argc, char *argv[])

  int i,n;  

n=0;  

while ( scanf("%s",s[n])!=EOF && s[n][0]!='#' )      n++;  

 

qsort(s,n,sizeof(s[0]),cmp);  

   for (i=0; i<n; i++)     

printf("%s\n",s[i]);    

 return 0;

}

 

 

 

 

 

尝试 3

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[10000][256];

int cmp ( const void *a , const void *b )
{   
  char *x=(char *)a,*y=(char *)b;
  int i=0,j=0;
if ( strlen(x)!=strlen(y) ) return  strlen(x)-strlen(y); 

while(x[i]) i++;
while(y[j]) j++;

if(i==j) return strcmp(x,y);
if(i!=j) return i-j; 
}


int main(int argc, char *argv[])
{   int i,n;
 n=0;
 while ( scanf("%s",s[n])!=EOF && s[n][0]!='#' ) n++; 
  qsort(s,n,sizeof(s[0]),cmp);
    for (i=0; i<n; i++)
     printf("%s\n",s[i]);     
 return 0;
}
View Code

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

char s[10000][256];

int cmp ( const void *a , const void *b )

{       

 char *x=(char *)a,*y=(char *)b;  

        int i=0,j=0;

 

if ( strlen(x)!=strlen(y) )            return  strlen(x)-strlen(y);

 

               while(x[i])      i++;

             while(y[j])       j++;

if(i==j)           return strcmp(x,y);

if(i!=j)              return i-j;

}

int main(int argc, char *argv[])

  int i,n;  n=0;  

while ( scanf("%s",s[n])!=EOF && s[n][0]!='#' )     n++;

  qsort(s,n,sizeof(s[0]),cmp);   

  for (i=0; i<n; i++)   

   printf("%s\n",s[i]);  

    return 0;

}




尝试4



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[10000][256];

int cmp ( const void *a , const void *b )
{   
  char *x=(char *)a,*y=(char *)b;
  int i=0,j=0;
  while(x[i]) i++;
while(y[j]) j++;

if ( strlen(x)!=strlen(y) ) return  strlen(x)-strlen(y); 
else if ( strlen(x)==strlen(y) ) return i-j; 



else return strcmp(x,y);
 
}


int main(int argc, char *argv[])
{   int i,n;
 n=0;
 while ( scanf("%s",s[n])!=EOF && s[n][0]!='#' ) n++; 
  qsort(s,n,sizeof(s[0]),cmp);
    for (i=0; i<n; i++)
     printf("%s\n",s[i]);     
 return 0;
}
View Code

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

char s[10000][256];

int cmp ( const void *a , const void *b )

{    

char *x=(char *)a,       *y=(char *)b;  

int i=0,j=0;  

 

while(x[i]) i++;

while(y[j]) j++;

 

  if ( strlen(x)!=strlen(y) )                             return  strlen(x)-strlen(y);

      else    if ( strlen(x)==strlen(y) )                 return i-j;

                    else                              return strcmp(x,y);  

}

int main(int argc, char *argv[])

{

   int i,n;

 n=0;  

while ( scanf("%s",s[n])!=EOF && s[n][0]!='#' )            n++;  

 

qsort(s,n,sizeof(s[0]),cmp);  

   for (i=0; i<n; i++)     

printf("%s\n",s[i]);    

 return 0;

}

 

 

***********************************************************************************************************************************************

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[10000][256];


int cmp ( const void *a , const void *b )
{   

char *x=(char *)a,*y=(char *)b; int i=0,j=0,k; k=0; while(x[k]) {if(x[k]=='1') i++; k++;} k=0; while(y[k]) {if(y[k]=='1') j++; k++;} if ( strlen(x)!=strlen(y) ) return strlen(x)-strlen(y); //串长度 是否 相等 if (i!=j) return i-j; // 1 的个数 比较 return strcmp(x,y); //ASC||码 比较 } int main(int argc, char *argv[]) { int i,n; n=0; while ( scanf("%s",s[n])!=EOF ) n++; qsort(s,n,sizeof(s[0]),cmp); for (i=0; i<n; i++) printf("%s\n",s[i]); return 0; } ******************************** #include <stdio.h> #include <stdlib.h> #include <string.h> char s[10000][256]; int one(char *x) { int c=0,i=0; while (x[i]!='\0') { if (x[i]=='1') c++; i++; } return c; } int cmp ( const void *a , const void *b ) { char *x=(char *)a,*y=(char *)b; int i=one(x),j=one(y),k; if ( strlen(x)==strlen(y) ) if (i==j) return strcmp(x,y); else return i-j; else return strlen(x)-strlen(y); } int main(int argc, char *argv[]) { int i,n; n=0; while ( scanf("%s",s[n])!=EOF ) n++; qsort(s,n,sizeof(s[0]),cmp); for (i=0; i<n; i++) printf("%s\n",s[i]); return 0; } ********************************************** #include <stdio.h> #include <stdlib.h> #include <string.h> char s[10000][256]; int one(char *x) { int c=0,i=0; while (x[i]!='\0') { if (x[i]=='1') c++; i++; } return c; } int cmp ( const void *a , const void *b ) { char *x=(char *)a,*y=(char *)b; int i=one(x),j=one(y),k; if ( strlen(x)!=strlen(y) ) return strlen(x)-strlen(y); if (i!=j) return i-j; return strcmp(x,y); } int main(int argc, char *argv[]) { int i,n; n=0; while ( scanf("%s",s[n])!=EOF ) n++; qsort(s,n,sizeof(s[0]),cmp); for (i=0; i<n; i++) printf("%s\n",s[i]); return 0; }

 

 

****************************************************************************************************************************************************

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

char s[10000][256];

 

int cmp ( const void *a , const void *b )

{  

char *x=(char *)a,     *y=(char *)b;

 

int i=0,j=0,k;

 

k=0; 

     while(x[k])      i=i+x[k]-'0',        k++  ;

k=0 ;

      while(y[k])    j=j+y[k]-'0',        k++   ;

   if ( strlen(x)==strlen(y) )       

         if (i==j)     return strcmp(x,y);      

           else         return i-j;    

     else    return  strlen(x)-strlen(y);

}

 

int main(int argc, char *argv[])

 

  int i,n;

 

 n=0;

 while ( scanf("%s",s[n])!=EOF  )    n++;  

 

qsort(s,n,sizeof(s[0]),cmp);    

for (i=0; i<n; i++)     

printf("%s\n",s[i]);    

 return 0;

 

}

 

 

 

 

 

#include <cstdio>
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;

struct Comp
{
    bool operator ()(const string &s1,const string &s2)
    {
        if(s1.length()!=s2.length()) return s1.length()<s2.length();
        int c1=count(s1.begin(),s1.end(),'1');
        int c2=count(s2.begin(),s2.end(),'1');
        return (c1!=c2?c1<c2:s1<s2);
    }
};
int main()
{
    multiset<string,Comp>ms;
    string s;
    while(cin>>s)
    {
        ms.insert(s);
    }
    for(multiset<string,Comp>::iterator it=ms.begin();it!=ms.end();it++)
    {
        cout<<*it<<endl;
    }
    return 0;
}

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/2014acm/p/3876433.html

<think>嗯,用户想用Python编写程序来找出指定范围内的所有完数。完数的定义是它的所有因子之和等于它本身,比如6就是1+2+3。那我得先理清楚思路,怎么实现这个功能。 首先,用户需要输入一个整数n,然后找出1到n之间的所有完数。根据引用里的例子,比如引用[3]和引用[4]中的Python代码,都是通过双重循环来实现的。外层循环遍历每个数i,内层循环找出i的所有因子,然后求和判断是否等于i。 那用户可能需要详细的步骤说明。比如,第一步是输入处理,确保n的范围正确。然后,对于每个数i,从1到n,计算它的因子和。计算因子的时候,可以优化一下,因子只需要检查到i的一半,比如引用[4]中提到用range(1, int(n/2)+1),但需要注意,这样可能会漏掉某些情况吗?其实,正确的做法应该是遍历到i的平方根,或者更简单地,遍历到i-1,因为除了自身之外的最大因子不会超过i的一半。不过,在引用[3]中的例子,他们遍历到i,也就是j从1到i-1,这样更准确,虽然效率可能稍低,但对于n不太大的情况,比如10000,应该还是可以的。 然后,当因子和等于i的时候,就记录这个数。同时,用户可能需要输出每个完数的因子分解形式,像引用[2]中的函数PrintPN那样。不过用户的问题描述中只提到输出完数,可能不需要分解式,但需要看用户的具体需求。 接下来,考虑如何优化因子和的计算。比如,可以遍历j从1到sqrt(i),然后同时累加j和i/j,但需要注意重复的情况,比如当i是平方数时,sqrt(i)会被加两次。或者像引用[4]中的做法,遍历到i的一半,不过这可能不如遍历到i的平方根高效。不过对于用户的问题来说,可能n的范围是1到10000,所以双重循环的时间复杂度还是可以接受的,特别是Python的效率在这种情况下可能足够。 然后,关于代码的结构。需要输入n,然后遍历每个数,计算因子和。比如,在引用[3]的代码中,他们使用了一个列表来保存因子,然后求和判断。但也可以直接累加,不需要保存列表,除非需要输出因子。如果用户需要输出因子的话,那么保存列表是有必要的。根据用户的问题,可能需要输出完数,所以是否需要因子列表取决于用户的需求,但根据样例输出,比如引用[1]中的C程序,只是输出完数本身,所以可能不需要因子列表。 不过用户提到“需要根据输入的整数n,输出从1到n之间的所有完数及其格式化结果”,这里的“格式化结果”可能指的是像引用[2]中的分解式。所以可能需要同时输出完数的等式,如6=1+2+3。这时候,就需要在找到完数时,同时收集它的因子,然后格式化成字符输出。 那这样的话,代码需要在内层循环中收集所有因子,然后求和判断是否等于i。如果是,就将因子列表转换成字符,用加号连接。例如,对于6,输出“6 = 1 + 2 + 3”。 所以,整个流程大概是: 1. 输入n,并验证n的范围是否符合要求(1≤n≤10000)。 2. 遍历i从1到n: a. 对于每个i,遍历j从1到i-1,找出所有能整除i的j,即为因子。 b. 将这些因子存入列表,并求和。 c. 如果和等于i,则记录i及其因子列表。 3. 对于所有找到的完数,按格式输出,每个完数一行,等式形式。 如果用户需要的是每个完数的分解式,那么必须保存因子列表,并排序后拼接成字符。否则,如果只需要输出完数本身,则不需要保存列表,直接输出i即可。 根据引用[3]中的代码,他们在找到完数时,会输出完数及其因子列表。而用户的问题中的样例输出如引用[1]中的C程序只是输出完数的数值,每行一个。所以可能需要确认用户的需求是否需要分解式。但用户的问题描述中提到“输出从1到n之间的所有完数及其格式化结果”,这里的格式化结果可能包括分解式。 因此,代码可能需要两个版本:一个是只输出完数本身,另一个是输出分解式。例如,用户的问题可能希望像引用[3]中的输出,显示完数的因子,或者像引用[2]中的函数PrintPN那样。 但根据用户给出的参考中的样例,例如引用[1]的样例输出是每行一个完数,所以可能用户只需要输出完数本身,每个一行。但用户的问题中提到“格式化结果”,可能需要更详细的输出。所以需要进一步明确。 可能用户的问题需要同时满足两种情况,或者根据不同的参数输出不同的结果。但根据用户的问题描述,可能更倾向于输出完数本身,因为给出的样例是每行一个数。比如,用户的问题中的样例输入10000输出四个数,每行一个。 所以,可能需要编写两种版本的代码:一个是仅输出完数,另一个是输出分解式。或者让用户选择。但根据用户的问题,可能主要是需要输出完数,而格式化结果可能指每个完数单独一行。 但用户的问题中的示例代码(引用[1]中的C程序)只输出完数本身,而引用[3]中的Python代码输出完数及其因子。所以需要确认用户的需求。根据问题中的用户提问部分,用户说:“需要根据输入的整数n,输出从1到n之间的所有完数及其格式化结果。”这里的“格式化结果”可能是指分解式,所以可能需要结合两种方式。 所以,最终的Python代码可能需要在找到完数后,输出完数本身,以及它的分解式。或者根据用户的选择来决定。但根据引用[3]中的例子,他们的代码是输出完数和因子列表,而用户的问题可能需要类似的功能。 综上,代码的大致步骤应该是: 1. 输入n,并检查n是否在1到10000之间。 2. 遍历每个i从1到n: a. 初始化sum为0,或者初始化一个列表来保存因子。 b. 遍历j从1到i//2,或者到i-1,检查是否是因子。 c. 如果是因子,则加到sum中,并保存到列表里。 d. 遍历结束后,比较sum是否等于i。如果是,则记录i和因子列表。 3. 输出所有完数,每个一行,可能包含分解式。 例如,对于完数6,输出“6 = 1 + 2 + 3”。 但根据用户提供的样例输出(如引用[1]中的C程序输出),可能只需要输出完数本身,每行一个。因此,可能需要两个版本的回答:一个仅输出完数,另一个输出分解式。但用户的问题中提到“格式化结果”,所以可能需要分解式。 因此,现在需要考虑如何编写代码,既输出完数,又输出其分解式。例如,像引用[3]中的代码那样,输出每个完数的因子列表,同时统计数量。 但用户的问题可能希望每个完数单独一行,分解式如“6 = 1 + 2 + 3”。所以代码需要将因子列表转换为用“+”连接的字符。 所以,在Python中,可以这样做:当找到一个完数i时,收集其所有因子(除了自身),然后排序,然后用“ + ”连接,然后输出“i = 因子列表”。 此外,需要处理n的范围,比如用户输入的是否有效,但根据问题中的输入描述,用户输入的是正整数n,1≤n≤10000,所以代码可能需要包含输入验证,但根据样例代码中的C程序,可能没有做输入验证,而是直接读取输入。 综上,Python代码的大致结构如下: n = int(input()) for i in range(1, n+1): factors = [] for j in range(1, i): if i % j == 0: factors.append(j) if sum(factors) == i: print(f"{i} = {' + '.join(map(str, factors))}") 不过,这样输出的每个完数都会显示分解式。如果用户只需要输出完数本身,那么可以简化: n = int(input()) for i in range(1, n+1): sum_factors = 0 for j in range(1, i): if i % j == 0: sum_factors += j if sum_factors == i: print(i) 但根据用户的问题中的样例输出(如引用[1]中的输出是每个完数一行),可能第二种方式更符合需求。但用户的问题提到“格式化结果”,所以可能需要第一种方式。不过需要明确用户的需求。 用户的问题描述中,参考的引用[2]提到了输出分解式,而引用[1]则只是输出完数。用户可能希望两种方式都有,或者根据不同的情况选择。 所以,可能需要在回答中包含两种方法的代码示例:一种仅输出完数,另一种输出分解式。 例如,第一种方法,仅输出完数: n = int(input()) for i in range(1, n+1): if sum(j for j in range(1, i) if i % j == 0) == i: print(i) 这种方法简洁,使用了生成器表达式来计算因子和。 第二种方法,输出分解式: n = int(input()) for i in range(1, n+1): factors = [j for j in range(1, i) if i % j == 0] if sum(factors) == i: print(f"{i} = {' + '.join(map(str, factors))}") 这样每个完数都会显示其因子分解式。 另外,需要考虑性能问题,因为当n较大时,例如10000,这样的双重循环可能比较慢。例如,对于i=10000,内层循环需要执行9999次判断。这时候,可以优化内层循环的范围。因为除了i本身之外的最大因子是i/2,所以可以遍历到i//2即可,减少循环次数。例如: factors = [] for j in range(1, int(i**0.5)+1): if i % j == 0: factors.append(j) if j != i // j and j != 1: factors.append(i // j) if sum(factors) == i - ... ? 不过这里需要注意,这种方法可能更复杂,因为需要处理平方根的情况,并且要排除i本身。可能更简单的优化是遍历到i//2,这样可以减少循环次数,例如: for j in range(1, i//2 + 1): if i % j == 0: sum += j 这样,当i是偶数时,最大的因子是i/2;当i是奇数时,最大的因子可能小于i/2。这样可以将内层循环的次数减少到i//2次,而不是i-1次。例如,当i=10000时,内层循环只需执行5000次,而不是9999次。这会提高效率。 所以,代码可以优化为: n = int(input()) for i in range(1, n+1): sum_factors = 0 for j in range(1, i//2 +1): if i % j == 0: sum_factors += j if sum_factors == i: print(i) 但这里需要测试是否正确,比如对于i=6,j的范围是1到3,所以j=1、2、3,其中i%j==0的是1、2、3,sum是6,正确。而对于i=28,因子包括1,2,4,7,14,它们的和是28。当j遍历到14的时候,i//2=14,所以j会到14,所以sum_factors将包括1+2+4+7+14=28,正确。所以这种优化是可行的。 所以,优化后的代码效率更高,特别是当n较大时。但需要注意的是,当i为1时,i//2是0,所以循环不会执行,sum_factors保持0,判断0==1不成立,正确。 综上,给出两种方法的代码,一种优化了内层循环,另一种更直观。用户可以根据需要选择。 另外,用户可能需要处理输入验证,比如确保n在1到10000之间。例如: n = int(input()) if n < 1 or n > 10000: print("输入超出范围") else: for i in range(1, n+1): ... 但根据问题中的样例输入,可能不需要处理,因为题目假设输入是合法的。 总结,编写Python程序的大致步骤是: 1. 输入n。 2. 遍历每个数i从1到n。 3. 对于每个i,计算所有小于i的因子之和。 4. 如果和等于i,则输出i或其分解式。 在代码实现时,可以选择是否优化内层循环的范围,以及是否输出分解式。</think>要使用Python编写程序找出指定范围内的完数,可以按照以下步骤实现: ### 实现步骤 1. **输入处理**:读取用户输入的正整数$n$,并验证其范围是否符合$1 \leq n \leq 10000$ 2. **因子计算**:对于每个数$i$(从$1$到$n$),计算其所有真因子(除自身外的因子)之和 3. **完数判断**:若因子和等于$i$,则记录该数 4. **输出结果**:按格式输出所有完数,每个占一行 ### 代码实现 #### 基础版(仅输出完数) ```python n = int(input()) for i in range(1, n + 1): if sum(j for j in range(1, i) if i % j == 0) == i: print(i) ``` #### 优化版(输出分解式) ```python n = int(input()) for i in range(1, n + 1): factors = [j for j in range(1, i) if i % j == 0] if sum(factors) == i: print(f"{i} = {' + '.join(map(str, factors))}") ``` ### 性能优化说明 1. **因子范围优化**:遍历范围可缩减为$1$到$\lfloor i/2 \rfloor$,减少循环次数[^4] ```python sum(j for j in range(1, i//2 + 1) if i % j == 0) ``` 2. **数学特性**:利用因子对称性(若$j$是因子,则$i/j$也是因子),可将遍历范围优化到$\sqrt{i}$[^4] ### 示例输出 当输入$n=10000$时,输出结果为: ``` 6 28 496 8128 ``` 若采用分解式版本,输出形式为: ``` 6 = 1 + 2 + 3 28 = 1 + 2 + 4 + 7 + 14 496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248 8128 = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 127 + 254 + 508 + 1016 + 2032 + 4064 ``` ### 关键点 - **因子和计算**:通过列表推导式或生成器表达式高效计算 - **格式输出**:使用`join`方法实现分解式格式化 - **边界处理**:当$i=1$时,因子和为$0$,不会误判为完数 ### 扩展应用 此方法可应用于寻找其他特殊数(如亲和数、盈数等),只需修改判断条件[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值