c语言之 练习题3 大贤者福尔(乘积),镂空等腰三角形,目录列表

本文是接着上一篇c语言之 练习题8 排队_水w的博客-CSDN博客

目录

 乘积

代码1:python

代码2:python

代码3:c++

镂空等腰三角形

代码:

执行结果: 

目录列表

代码1:

代码2:

执行结果:


 乘积

大贤者福尔的数学研究成绩斐然,影响力越来越大,也有很多人向他请教。最近,有人咨询他一个问题。给定若干个整数S = {S_1, S_2,...,S_n}S=S1​,S2​,...,Sn​,其中若干个连续的数的最大乘积是多少?

福尔觉得这个问题太简单,他想把这个问题作为对你的考验,你能够解出来吗?

  • 输入:输入数据有若干行,每行包含N(1 \le N \le 18)N(1≤N≤18)个空格分隔的整数SS,每个整数S_iSi​的范围为-10 \le S_i \le 10−10≤Si​≤10。
  • 输出:对每行输入数据,先在单独的行中输出如Case x: ans from-to的测试样例信息,x为测试样例编号,从1开始,ans为满足要求的最大乘积及对应的起止范围,若有多个连续序列满足条件,选择范围最小的序列,若存在多个相同范围的序列,取起始位置最小的序列,起始位置从0开始计算。
  • 示例输入:
1
1 2
-1 1
-1 0 1
1 1 9
  • 示例输出:
Case 1: 1 0-0
Case 2: 2 1-1
Case 3: 1 1-1
Case 4: 1 2-2
Case 5: 9 2-2

代码1:python

a = []
tot = 0

'''大贤者福尔的数学研究成绩斐然,影响力越来越大,也有很多人向他请教。最近,有人咨询他一个问题。
给定若干个整数S=S1​,S2​,...,Sn​,其中若干个连续的数的最大乘积是多少?'''

def f(st, l):
    ans = 1
    for i in range(st, st + l):
        ans *= a[i]
    return ans

try:
    while True:
        a = [int(x) for x in input().split()]
        n = len(a)
        ma = - 1000
        st = 0
        l = 0
        for i in range(1, n + 1):
            for j in range(n - i + 1):
                t = f(j, i)
                if (t > ma):
                    st = j
                    l = i
                    ma = t
        tot += 1
        print("Case {}: {} {}-{}".format(tot, ma, st, st + l - 1))
except:
    pass

代码2:python

'''大贤者福尔的数学研究成绩斐然,影响力越来越大,也有很多人向他请教。最近,有人咨询他一个问题。
给定若干个整数S=S1​,S2​,...,Sn​,其中若干个连续的数的最大乘积是多少?'''

if __name__ == '__main__':
    import sys

    lines = list(map(str.strip, sys.stdin.readlines()))
    for id, line in enumerate(lines):
        nums = list(map(int, line.split()))
        if len(nums) == 1:
            print(f'Case {id + 1}: %s %s-%s' % (nums[0], 0, 0))
        else:
            res = {}
            for i in range(len(nums)):
                val = 1 * nums[i]
                if val not in res:
                    res[val] = []
                res[val].append([i, i])
                for j in range(i + 1, len(nums)):
                    val *= nums[j]
                    if val not in res:
                        res[val] = []
                    res[val].append([i, j])
            max_value = max(res.keys())
            max_pos_l = res[max_value]
            range_dict = {}
            for v in max_pos_l:
                t = v[1] - v[0]
                if t not in range_dict:
                    range_dict[t] = []
                range_dict[t].append(v)
            min_l = sorted(range_dict[min(range_dict.keys())], key=lambda x: (x[0], x[1]))
            print(f'Case {id + 1}: %s %s-%s' % (max_value, min_l[0][0], min_l[0][1]))

代码3:c++

#include<stdio.h>

/*
大贤者福尔的数学研究成绩斐然,影响力越来越大,也有很多人向他请教。最近,有人咨询他一个问题。
给定若干个整数S=S1​,S2​,...,Sn​,其中若干个连续的数的最大乘积是多少?
*/

int main(){
    short data[18] = {0};
    short i = 0, j, k, p, minSpan;
    long Max, S;
    short L = 1;
    bool flag;
    while(scanf("%hd", data + i) != EOF){
        i ++;
        if(getchar() == '\n'){
            /* 遇到回车符, 意味着一轮输入结束 */
            /* 至此共输入了i个数据 */
            Max = data[0];
            /* printf("i = %hd\n", i); */
            for(j = 0; j < i; j ++)
            {
                for(k = j; k < i; k ++)
                {
                    S = 1;
                    for(p = j; p <= k; p ++)
                    {
                        S *= data[p];
                    }
                    if(S > Max)
                    {
                        Max = S;
                    }
                }
            }
            /* printf("Max = %ld\n", Max); */
            /* 至此已找到最大连续乘积 */
            /* 开始匹配 */
            minSpan = 17;
            for(j = 0; j < i; j ++){
                for(k = j; k < i; k ++){
                    S = 1;
                    for(p = j; p <= k; p ++){
                        S *= data[p];
                    }
                    if(S == Max){
                        /* printf("%hd-%hd\n", j, k); */
                        /* 匹配成功 */
                        if(k - j < minSpan){
                            minSpan = k - j;
                        }
                    }
                }
            }
            /* printf("minSpan = %hd\n", minSpan); */
            /* 至此确定了最小跨度 */
            flag = false;
            for(j = 0; j < i && flag == false; j ++){
                for(k = j; k < i && flag == false; k ++){
                    S = 1;
                    for(p = j; p <= k; p ++){
                        S *= data[p];
                    }
                    if(S == Max){
                        if(k - j == minSpan){
                            flag = true;
                            printf("Case %hd: ", L ++);
                            printf("%ld ", Max);
                            printf("%hd-%hd\n", j, k);
                        }
                    }
                }
            }
            i = 0;
        }
    }
    return 0;
}

镂空等腰三角形

请通过函数实现,输出底边长为 nn 的镂空等腰三角形。

  • 输入:标准输入,包括两部分:c,n(0 \lt n \le 100,)c,n(0<n≤100,),cc为指定输出的ASCII字符,nn为指定的边长。
  • 输出:用指定的字符输出边长为nn的镂空等腰三角形。
  • 示例输入:
x 3
  • 示例输出:
  x
 x x
x x x

代码:

#include <iostream>
using namespace std;
int main(){
    char c;     
	int a;
    cin>>c>>a;
    for(int i=1;i<a+1;i++){ 
    	if(i==1){   
    		for(int k=1;k<=a-i;k++){  
                cout<<" ";
            }
            cout<<c;
            cout<<endl;
		}
    	else if(i==a){  
    		for(int j=1;j<i;j++){
    			cout<<c<<" ";
			}
			cout<<c<<endl;
		}
		else{      
			for(int k=1;k<=a-i;k++){
                cout<<" ";
            }
            cout<<c;
            for(int m=1;m<=2*(i-1)-1;m++)
            cout<<" ";
            cout<<c;
           cout<<endl;
		}
    }
    return 0;	
}

执行结果: 

目录列表

命令行中有一个列目录的程序,可以按照指定的方式将目录中的文件罗列出来。小A想进一步改进列表程序,希望在给定的显示宽度限制下用最少的行格式化输出所有的文件名,且排在前面的行尽可能满列。

显示规则为:文件列表按字典序左对齐的方式显示为若干列,列宽由文件名的最大长度确定,列间用2个空格分割,最后一列后无空格。

  • 输入:输入数据有若干组,每组为待罗列的文件名列表,格式如下: 每组的第一行为空格分隔的两个整数n,w(0 \lt n \le w)n,w(0<n≤w),分别为该组文件的数量和一行能够显示的宽度。随后的nn行中,每行为一个文件名,保证每个文件名最长不超过指定的显示宽度。
  • 输出:对每组输入,先根据要求的宽度输出对应个-,随后按要求输出若干列格式化的文件名列表,所有列表中文件名自上而下、从左到右按字典序排列。
  • 示例输入:
20 60 
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
  • 示例输出:
------------------------------------------------------------↵
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t↵
----------↵
a  d  g  i↵
b  e  h  j↵
c  f↵

代码1:

#include<iostream>
#include<algorithm>
#include <iomanip>
using namespace std;
int n,m;
string s[10000]; 
int main(){
	while(cin>>n>>m){
		int maxlen=0;
		for(int i=1;i<=n;i++){
			cin>>s[i];
			int tmplen=s[i].length();
			maxlen=max(maxlen,tmplen);
		}
		maxlen+=2;
		int num=m/maxlen;//每一行可以放的字母数 
		if(m-maxlen*num>=maxlen-2)num++;
		int hang=n/num,over_num=0;//行数
		int over_hang=hang;
		if(num*hang<n)over_hang=hang+1,over_num=n-num*hang;
		sort(s+1,s+1+n);
		for(int i=1;i<=m;i++)cout<<"-";
		cout<<endl;
		for(int i=1;i<over_hang;i++){
			int h=-over_hang;
			for(int j=1;j<num;j++){
				if(j-1<=over_num){
					h+=over_hang;
					cout<<left<<setw(maxlen)<<s[i+h];
				}
				else{
					h+=hang;
					cout<<left<<setw(maxlen)<<s[i+h];					
				}
			}
			if(num-1<=over_num)cout<<s[i+h+over_hang]<<endl;
			else cout<<s[i+h+hang]<<endl;
		} 
		//最后一行单独输出 
		if(over_num==0)over_num=num;
		for(int j=1;j<over_num;j++){
			cout<<left<<setw(maxlen)<<s[over_hang+(j-1)*over_hang];
		}
		cout<<s[over_hang+(over_num-1)*over_hang]<<endl;
	}
}

代码2:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;
int main(){
    int n, w;
    while(cin >> n >> w){
        string s[n];
        for(int i=0; i<n; i++)
            cin >> s[i];
        int maxlen = s[0].length();
        for (int i = 1; i < n; ++i) {
            if(s[i].length()>maxlen){
                maxlen = s[i].length();
            }
        }
        sort(s, s+n);
        for (int i = 0; i < w; ++i) {
            cout << "-";
        }
        cout << endl;
        int y = (w+2)/(maxlen+2); //最少列
        int x = ceil((double)n/y);//每列多宽
        if(x==1){
            int a = 0;//记录列数
            for (int i = 0; i < y; ++i) {
                cout << s[i];
                for(int j=0; j<maxlen+2-s[i].length(); j++){
                    if(a == y-1) break;
                    cout << " ";
                }
                a++;
            }
            cout << endl;
        }
        else if(n%y==0){
            for (int i = 0; i < x; ++i) {
                int a=0, index = i;
                while(a < y){
                    cout << s[index];
                    for(int j=0; j<maxlen+2-s[index].length(); j++){
                        if(a==y-1) break;
                        cout << " ";
                    }
                    a++;
                    index += x;
                }
                cout << endl;
            }
        }
        else{
            for(int i=0; i<x-1; i++){
                int a=0, index = i;
                while(a < n%y){
                    cout << s[index];
                    for(int j=0; j<maxlen+2-s[index].length(); j++){
                        cout << " ";
                    }
                    a++;
                    index += x;
                }
                while (a >= n%y && a < y){
                    cout << s[index];
                    for(int j=0; j<maxlen+2-s[index].length(); j++){
                        if(a == y-1) break;
                        cout << " ";
                    }
                    a++;
                    index = index + x - 1;
                }
            }
        }
    }
}

执行结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值