user-0 提问: 贪心。。。。

回复:
user: user-1
content: 今天有考虑了一下，觉得还是没有必要排序，贪心法也许会用。   #include<stdio.h>  #define N 9 int doaGroup(FILE *fpin,FILE *fpout) //处理一组数据 V,a[1]..a[9] 共两行。 {     int V ;     // V  这是题目给的，似乎也应该这样命名     int a[N+1]; // ai 这也是题目给 a1...a9: Paints count for number i = 1..9     int i,j;      // i 和  ai 对应的 i; Tom heard that Mary doesn’t like zero 所以只有1..9     int minpaints,minpos; //写每个数字需要的paints中 最小paints 。和他的位置     int repeat,val;      //要写的数字和重复次数。     int replaceRepeat, replaceVal,remain; //替换数字的重复次数，替换的数字，没有用完的paints      if(feof(fpin))return 0; //文件结束，不再处理      fscanf(fpin, "%d", &V);      if(feof(fpin))return 0; //文件结束，不再处理      for(i = 1 ; i <= N; i++)     {         fscanf(fpin , "%d" , &a[i]);     }     for(i = 2 , minpos = 1; i<= N ; i++)     {         if(a[ i ] <= a[ minpos ]) //保险起见，用<= 保证选最大的数字         minpos =i;     }     minpaints = a[ minpos ];     val = minpos ;     repeat = V / minpaints;     remain =V % minpaints;       if(repeat < 1){         fprintf(fpout,"-1\n");     }else{         //依次用当前最大的数字替换val         //选最小的时候确保了比val 大的位置i，不会有相等的paints 了         //val         for(j = N ; remain >0 && j > val ; j-- )         {             int diff =   (a [j] - a[val]);//paints差,val的paints 是最小值，所以 diff > 0              replaceVal = j;             replaceRepeat = remain / diff;             remain %= diff;             repeat -= replaceRepeat ;             while(replaceRepeat--)                 fprintf(fpout,"%d",replaceVal);             //if(repeat == 0 )break;         }         while(repeat--)            fprintf(fpout,"%d",val);     }       return 1; }  int main() {     FILE *fpin,*fpout;     char infile[80]="in.txt";     char outfile[80]="out.txt";     if(NULL==(fpin = fopen(infile,"rt"))){         printf("Error !Cannot open %s for read\n",infile);         return -1;     }     if(NULL == ( fpout = fopen(outfile,"wt"))){         printf("Error !Cannot open %s for write\n");         fclose(fpin);         return -2;     }     while( doaGroup(fpin , fpout))         fprintf(fpout,"\n");      fclose(fpout);     fclose(fpin);      return 0; }  测试了一下，3组数据都正确。  int V，      0 ~ 10^6 没问题 int a[N+1];  1 ~  10^5 没问题

user: user-1
content: 难道输出 21 这样的话，排序确实是必要的。 不过  ai 的最大值是10^5 V 的最大值是10^6 h[30000]; 似乎不够呀  假设 需要写 10^6 个数字你H似乎不够。  我觉得 增加一个数组表示每个数重复次数就够了 先取需要paints的 最小值，求重复次数 再取次小值，并且序号比前一大的，求可以替换多少。 序号不大就不替换。  最多替换9次就可以了。 然后，按照重复次数，写数据就可以了。 这确实就是贪心法了。  貌似sort不是稳定排序。 就是说相同的数据可能会颠倒顺序。 你看是否这个原因！

user: user-2
content: 我这编译测试没问题。。。 测试结果： 5 5 4 3 2 1 2 3 4 5 //输入 55555 //输出 2 9 11 1 12 5 8 9 10 6 //输入 33 //输出

user: user-0
content: 引用 11 楼 lm_whales 的回复: //val = minpos ;  //repeat = val / minpaints;  //应为 val = minpos ;  repeat = V / minpaints;  ///////////////////  //while(doaGroup(fpin,fpout)); //应为  while(doaGroup(fpin,fpout))        printf("\n"); //成功输出换行 //如果最后一批数据，不换行，先测试一下即可；     [quote=引用 10 楼 lm_whales 的回复:]  #include<stdio.h>  #define N 9 int doaGroup(FILE *fpin,FILE *fpout) //处理一组数据 V,a[1]..a[9] 共两行。 { int V ;     // V  这是题目给的，似乎也应该这样命名      int a[N+1]; // ai 这也是题目给 a1...a9: Paints count for number i = 1..9   int i;      // i 和  ai 对应的 i; Tom heard that Mary doesn’t like zero 所以只有1..9 int minpaints,minpos; //写每个数字需要的paints中 最小paints 。和他的位置 int repeat,val;       //要写的数字和重复次数。 if(feof(fp))return 0; fscanf(fpin, "%d", &V); if(feof(fpin))return 0; for(i = 1 ; i <= N; i++) {     fscanf(fpin , "%d" , &a[i]); } for(i = 2 , minpos = 1; i<= N ; i++) {    if(a[ i ]<= a[ minpos ]) //保险起见，用<= 保证选最大的数字         minpos =i; } minpaints = a[ minpos ]; val = minpos ; repeat = V / minpaints; if(repeat < 1 ){printf(fpout,"-1\n");} else{    for(i=0;i<repeat;i++)        printf(fpout,"%d",val);}  return 1; }  int main() { FILE *fpin,*fpout; char infile[80]="in.txt"; char outfile[80]="out.txt"; if(NULL)==(fpin = fopen(infile,"rt"))){ printf("Error !Cannot open %s for read\n",infile);  return -1; } if(NULL)==(fpout = fopen(outfile,"rt"))){ printf("Error !Cannot open %s for write\n"); fclose(fpin); return -2; }  while( doaGroup(fpin , fpout))    printf("\n");  fclose(fpout); fclose(fpin);  return 0; } 我的理解是，Tom 用所拥有的paints 写用同一数字组成的最大的数 这样，就和 这个数字是哪一个无关了，只和重复次数有关了。 3位数总比2位数大，求做小值的时候，又选了paints的最小值中数字最大的数。  如果我的理解是对的，似乎这么处理就行了，不知道你排序做什么？[/quote] 5 2 3 9 9 9 9 9 9 9 这个输出结果你觉得应该是什么。

user: user-1
content: 是否需要在没用到的paints处理一下，把剩下的那些paints处理掉，让他比同一数字重复要大？？？？

user: user-1
content: //val = minpos ;  //repeat = val / minpaints;  //应为 val = minpos ;  repeat = V / minpaints;  ///////////////////  //while(doaGroup(fpin,fpout)); //应为  while(doaGroup(fpin,fpout))        printf("\n"); //成功输出换行 //如果最后一批数据，不换行，先测试一下即可；  引用 10 楼 lm_whales 的回复: #include<stdio.h>  #define N 9 int doaGroup(FILE *fpin,FILE *fpout) //处理一组数据 V,a[1]..a[9] 共两行。 { int V ;     // V  这是题目给的，似乎也应该这样命名      int a[N+1]; // ai 这也是题目给 a1...a9: Paints count for number i = 1..9   int i;      // i 和  ai 对应的 i; Tom heard that Mary doesn’t like zero 所以只有1..9 int minpaints,minpos; //写每个数字需要的paints中 最小paints 。和他的位置 int repeat,val;       //要写的数字和重复次数。 if(feof(fp))return 0; fscanf(fpin, "%d", &V); if(feof(fpin))return 0; for(i = 1 ; i <= N; i++) {     fscanf(fpin , "%d" , &a[i]); } for(i = 2 , minpos = 1; i<= N ; i++) {    if(a[ i ]<= a[ minpos ]) //保险起见，用<= 保证选最大的数字         minpos =i; } minpaints = a[ minpos ]; val = minpos ; repeat = V / minpaints; if(repeat < 1 ){printf(fpout,"-1\n");} else{    for(i=0;i<repeat;i++)        printf(fpout,"%d",val);}  return 1; }  int main() { FILE *fpin,*fpout; char infile[80]="in.txt"; char outfile[80]="out.txt"; if(NULL)==(fpin = fopen(infile,"rt"))){ printf("Error !Cannot open %s for read\n",infile);  return -1; } if(NULL)==(fpout = fopen(outfile,"rt"))){ printf("Error !Cannot open %s for write\n"); fclose(fpin); return -2; }  while( doaGroup(fpin , fpout))    printf("\n");  fclose(fpout); fclose(fpin);  return 0; } 我的理解是，Tom 用所拥有的paints 写用同一数字组成的最大的数 这样，就和 这个数字是哪一个无关了，只和重复次数有关了。 3位数总比2位数大，求做小值的时候，又选了paints的最小值中数字最大的数。  如果我的理解是对的，似乎这么处理就行了，不知道你排序做什么？

user: user-1
content: #include<stdio.h>  #define N 9 int doaGroup(FILE *fpin,FILE *fpout){ int V ; int a[N+1]; int i; int minpaints,minpos; int repeat,val; if(feof(fp))return 0; fscanf(fpin, "%d", &V); if(feof(fpin))return 0; for(i = 1 ; i <= N; i++) {     fscanf(fpin , "%d" , &a[i]); } for(i = 2 , minpos = 1; i<= N ; i++) {    if(a[ i ]<a[ minpos ])         minpos =i; } minpaints = a[ minpos ]; val = minpos ; repeat = val / minpaints; if(repeat < 1 ){printf(fpout,"-1\n");} else{    for(i=0;i<repeat;i++)        printf(fpout,"%d",val);}  return 1; }  int main() { FILE *fpin,*fpout; char infile[80]="in.txt"; char outfile[80]="out.txt"; if(NULL)==(fpin = fopen(infile,"rt"))){ printf("Error !Cannot open %s for read\n",infile);  return -1; } if(NULL)==(fpout = fopen(outfile,"rt"))){ printf("Error !Cannot open %s for write\n"); fclose(fpin); return -2; }  while(doaGroup(fpin,fpout));  fclose(fpout); fclose(fpin);  return 0; } 如果我的理解是对的，似乎这么处理就行了，不知道你排序做什么？

user: user-0
content: 引用 8 楼 lm_whales 的回复:这个题目要做的事情似乎如下： 1）找出a[i]的最小值和最小值所在的位置i 2）找出要写的数：      最小值的位置i，就是要写的数 3）找出要写几个数：      n = V/最小值， 就是写的个数  如果个数 n <1 输出-1  原因a[i] 是写某个数需要的Paint 的数目 V是拥有 的 Paint 的数目  这个题目似乎不需要贪心法，也许是我的理解有错误？应该这样、我感觉我的程序思路没错啊。测试数据也没有，就是AC不过。

user: user-1
content: 这个题目要做的事情似乎如下： 1）找出a[i]的最小值和最小值所在的位置i 2）找出要写的数：      最小值的位置i，就是要写的数 3）找出要写几个数：      n = V/最小值， 就是写的个数  如果个数 n <1 输出-1  原因a[i] 是写某个数需要的Paint 的数目 V是拥有 的 Paint 的数目  这个题目似乎不需要贪心法，也许是我的理解有错误？

user: user-0
content: 引用 6 楼 cfjtaishan 的回复:引用 5 楼 lavendermaple 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] 我在linux下编译和测试都没有问题哦！！但是我在那个上面AC不过。。。估计特殊数据有错误。我也找不出来。所以来这问问。 你是在windows下编译的吗，我不确定在windows下编译会是什么结果？！[/quote]我这是ACM ，应该和系统没问题。估计哪里思维搞错了。代码错误。

user: user-3
content: 引用 5 楼 lavendermaple 的回复:引用 4 楼 cfjtaishan 的回复:我在linux下编译和测试都没有问题哦！！但是我在那个上面AC不过。。。估计特殊数据有错误。我也找不出来。所以来这问问。 你是在windows下编译的吗，我不确定在windows下编译会是什么结果？！

user: user-0
content: 引用 4 楼 cfjtaishan 的回复:我在linux下编译和测试都没有问题哦！！但是我在那个上面AC不过。。。估计特殊数据有错误。我也找不出来。所以来这问问。

user: user-3
content: 我在linux下编译和测试都没有问题哦！！

user: user-0
content: 引用 2 楼 yulitingfeng 的回复:我这编译测试没问题。。。 测试结果： 5 5 4 3 2 1 2 3 4 5 //输入 55555 //输出 2 9 11 1 12 5 8 9 10 6 //输入 33 //输出程序有错误。不知道哪错了。答案错误。；

user: user-0
content: 坐等回答。。。。