华师大 OJ 3026

题目链接:点击打开链接


这个题目做了2个小时。这些代码的确是值得学习借鉴的。


解决方案:


#include <string.h>
#include <stdio.h>



void solve();

int main()
{
    int t,k;
    scanf("%d",&t);
    for(k = 0;k<t;k++){
        printf("case #%d:\n",k);
        solve();
    }
}

void solve(){
    int words_len;
    int words_count;
    int space;
    int str_len;
    int line_len;
    int i,j,start,p,l;
    char s[2001];
    scanf("%d\n",&line_len);
    gets(s);
    str_len = strlen(s);
    for(i = 0;s[i] ==' ';i++);//跳过行首空格
    while(i<str_len){
        start = i;//start记录每一行要输出的第一个单词的起始位置
        words_len = 0;  //统计每一行要输出的单词总长度
        words_count = 0;   //统计每一行要输出的单词个数
        for(;words_len + words_count <= line_len && i<str_len;){
            for(l = 0,p=i; s[p]!=' ' && p<str_len;p++,l++);//查找下一个单词以及长度
            if(words_len+words_count+l<=line_len){
                words_len+=l;
                words_count++;
                for(i=p;s[i]==' ';i++);//跳过空格
            }
            else break;
        }
        space = line_len - words_len;
        j = start;
        words_count--;
        while(j<i){
            while(s[j]!=' ' && j<str_len) putchar(s[j++]);
            while(s[j] ==' ' &&j<str_len) j++;
            if(i==str_len && words_count)
                putchar(' ');
            else{
                for(p=0; words_count && p<space/words_count;p++)
                    putchar(' ');
                space -= p;
            }
            words_count--;
        }
        putchar('\n');
    }



}

我自己的实现:
//17:44-->
#include <stdio.h>
#include <string.h>


void solve();

int main(){
    int t;
    int k;
    scanf("%d",&t);
    for(k = 0;k<t;k++){
        printf("case #%d:\n",k);
        solve();
    }
}

// 0. const int max = 2000;  读入一行的宽度到int M里面。
 //1. 读入数据,把一行的内容直接保存到一个char[max+1]里面。
 //2. 把单词从这里面识别出来,按顺序保存到record[max][35+5]里面,并且记录一共有多少个单词需要排版,保存到number_words里面。
 //3. 对record进行遍历,按照要求输出每一行的内容。

//    3.1 把将要输出的一行整理好,保存到一个数组里面:char line[M+1]; line[M] = '\0' ,这里的M是一行的宽度
//       3.1.1 定义几个变量: count_word, count_space, count_total

const int max = 2000;


void solve(){
    int line_len;
    int k,i;
    int M;
    char record[max][40];
    int number_words;
    char str_in[max+1];
    int count_words, count_space, count_total,index;
    char line[70+1];
    int count;
    int t,q,r;
    int flag;  //flag==1代表是最后一行了。==0代表还不是最后一行

// Initialization
    number_words = 0;


    scanf("%d\n",&line_len);
    gets(str_in);

// step 2.
    k = 0;
    i = -1;
    while(str_in[k]){
        if(str_in[k] == ' '){
            if(k==i+1){
                i = k;
            } else {
                record[number_words][k - i - 1]='\0';
                number_words++;
                i = k;
            }
        } else{
            record[number_words][k-i-1] = str_in[k];
        }
        k++;
    }
    if(str_in[k-1]!= ' ') {
        record[number_words][k-i-1] = '\0';
        number_words++;
    }

// step 3.
    index = 0; //用来指向record里面第几个单词
    while(1){// 一次输出一行,直到最后一行已经被输出了
        count_words = 0;  // 用来记录现在已经有多少个单词了
        count_space = 0;  // 用来记录到现在为止至少需要的空格的个数,
                          //在确定放不下下一个单词的时候,再来修改。
                          //如果已经没有单词了的话,那么就不再进行修改,而是将line[line_len] = '\0'

        count_total = 0;  // 用来记录到现在为止占用了多少个

        flag = 0;

        count_words = 1; //先不管,读入一个数据,然后在接下来的while循环里面继续读取
        count_total = strlen(record[index]);
        index++;//index代表将要读取的数组下标

        while(count_total <= line_len){
            if(index == number_words){
                flag = 1;
                break;
            } else if (index <= number_words-1){
                if(count_total + 1 + strlen(record[index]) <= line_len){
                    count_words++;
                    count_total = count_total + 1 + strlen(record[index]);
                    index++;
                } else { //说明这一行已经容纳不下多余的单词了
                    break;
                }
            }
            //要输出的是 index-1,index-1,index-2,index - count_words
        }

        count = 0;
        if(flag == 0){
            t = 0;
            for(k=index-1; k >= index-count_words;k--){
                t += strlen(record[k]);
            }
            count_space = line_len - t;
            q = count_space / (count_words - 1);
            r = count_space % (count_words - 1);
            for(k=0; k <= count_words-2;k++){
                printf("%s",record[index-count_words + k]);
                count++;
                if(count <= count_words - 1 - r)
                {
                    for(i=0;i<q;i++){
                        printf(" ");
                    }
                } else {
                    for(i = 0; i < q+1;i++){
                        printf(" ");
                    }
                }

            }
            printf("%s\n",record[index-count_words+k]);
        } else if(flag == 1){
            for(k=0;k<=count_words-2;k++){
                printf("%s ",record[index-count_words+k]);
            }
            printf("%s\n",record[index - count_words+k]);
            break;
        }
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值