PAT乙级1001-1020

于由astupidcoder发布

乙级题目很多基础题,加上一些针对C语言的特定坑。
用python直接砍瓜切菜。
每20道题开个新帖

1001 害死人不偿命的(3n+1)猜想

#include<stdio.h>

int main(){

  int d;
  scanf("%d",&d);

  int times = 0;

  while(d != 1){
    if (d%2){ //奇数
      d = (3 * d + 1 )/ 2;
    }else{ //偶数
      d = d / 2;
    }
    ++times;
  }

  printf("%d",times);

  return 0;

}

1002 写出这个数

#include<iostream>
#include<string>
#include<vector>

using namespace std;

vector<string> chinese = {
  "ling",
  "yi",
  "er",
  "san",
  "si",
  "wu",
  "liu",
  "qi",
  "ba",
  "jiu"
};

int main(){

  string inp;
  cin >> inp;
  int rint = 0;
  for (auto c:inp){
    rint += c - 48;
  }

  string rstr = to_string(rint);
  string outs;
  for (int i = 0 ; i != rstr.size() - 1 ; ++i){
    outs += chinese[rstr[i]-48] + " ";
  }
  outs += chinese[rstr[rstr.size() - 1] - 48];
  cout << outs;
  return 0;
}

1003 我要通过

#include<iostream>
#include<string>
#include<vector>

using namespace std;

bool test_ok(string &);

int main(){

  int num;
  cin >> num;
  vector<bool> result(num,false);

  string input;
  for(int i = 0 ; i != num ; ++i){
    cin >> input;
    result[i] = test_ok(input);
  }

  for(int i = 0 ; i <= num - 1 ; ++i){
    if (result[i])
      cout << "YES" <<endl;
    else cout << "NO" << endl;
  }

  return 0;
}

bool test_ok(string &ss){

  bool P = false,T = false;  //分别表示P或者T有没有出现
  int foreA = 0, middA = 0, tailA= 0;//分别表示P前,PT中间,T后的A的数量
  bool ok = true;

  for (auto c:ss){
    if (c == 'A'){
      if (!P)
        ++foreA;
      else if (!T)
        ++middA;
      else ++tailA;
    }else if (c == 'P'){
      if (P || T){  //重复出现了P,或者在T后面出现了P
        ok = false;
        break;
      }else
        P = true;
    }else if (c == 'T'){
      if (!P || T){//出现在P前面或者已经出现过T
        ok = false;
        break;
      }else
        T = true;
    }else{ //非PAT字符
      ok = false;
      break;
    }
  }

  if (!ok)
    return false;
  if (!P || !T)
    return false;

  if (middA == 0)
    return false;

  if (foreA == tailA && middA == 1)
    return true;
  else if (foreA == 0 && tailA == 0)
    return true;
  else if (tailA == middA * foreA)
    return true;
  else return false;

}

1004 成绩排名

d = int(input())
min = 101
max = -1
for i in range(0,d):
  line = input().split(' ')
  line[2] = int(line[2])
  if line[2] > max:
    max = line[2]
    high= line
  if line[2] < min:
    min = line[2]
    low = line

print(high[0],high[1])
print(low[0],low[1])

1005 继续3N+1猜想

K = int(input())

seq = input().split(' ')
seqn = [int(c) for c in seq]
done = []  #已验证过的
for c in seqn:
  while c != 1:
    if c % 2:
      c = (3 * c + 1 )/2
      done.append(c)
    else:
      c = c / 2;
      done.append(c)

for i in done:
  if i in seqn:
    seqn.remove(i)

seqn.sort(reverse = True)

for i in seqn[:-1]:
  print(i,end=" ")

print(seqn[-1])

1006 换个格式输出整数

c = int(input())
outstr=""

if int(c/100):
  outstr = outstr + "B"*int(c/100);
  c = c % 100

if int(c/10):
  outstr = outstr + "S"*int(c/10);
  c = c % 10

for i in range(1,c+1):
  outstr = outstr + str(i)

print(outstr)

1007 素数对猜想

//难点在于素数测试函数的设计,只要够高效就能过
//思路是在传参到素数测试函数时就只测奇数,在素数测试函数内部,也只用奇数当因子
//而且最大测到平方根,因为超过平方根以后显然就成了3*5和5*3的关系,不用测。
#include<stdio.h>
#include<math.h>

int is_su(int);

int main(){

  int top;
  scanf("%d",&top);
  int result = 0;
  for ( int i = 3 ; i <= top - 2 ; i += 2){ //保证传过去的都是奇数
    if (is_su(i) && is_su(i+2))
      ++result;
  }

  printf("%d",result);

  return 0;
}

int is_su(int test){

  int bbb = 1;
  for (int i = 3 ; i <= (int)sqrt(test) ; i += 2){   //偶数因子不用测
    if ( !(test % i) )
      bbb = 0;
  }
  return bbb;

}

1008 数组元素循环右移

#include<stdio.h>

void print_nums(int *, int);
int gcd(int a ,int b);

int main(){

  int len,M;
  scanf("%d %d",&len,&M);
  M = M % len;
  int nums[len];
  for(int i = 0 ; i != len ; ++i){
    scanf("%d",&nums[i]);
  }
  if ( !M )   //M是0,直接输出
    print_nums(nums,len);
  else{
    int yueshu = gcd(len,M);
    for (int i = 0 ; i != yueshu ; ++i){
      int reserve = nums[ i - M + len];
      for(int j = 0 ; j != len / yueshu ; ++j ){
        int temp = nums[(i + j * M) % len];
        nums[(i + j * M) % len] = reserve;
        reserve = temp;
      }
    }
    print_nums(nums,len);
  }
  return 0;
}

void print_nums(int *nums,int len){
  for (int i = 0 ; i != len -1 ; ++i){
    printf("%d ",nums[i]);
  }
  printf("%d",nums[len-1]);
}

int gcd(int a,int b){

  return b==0 ? a : gcd(b,a%b);

}

1009 说反话

#python简直是送的,翻转链表?不存在的,不知道什么叫翻转链表。

input_words = input().split(' ')
input_words.reverse()

output_str = " ".join(input_words).strip();

print(output_str)

1010 一元多项式求导

#include <stdio.h>

int main()
{
    int m,n;
    int flag=1;
    while(scanf("%d %d",&m,&n)!=EOF){
        if(n>0){
            if(flag==1){
                printf("%d %d",m*n,n-1);
                flag=0;
            }else{
                printf(" %d %d",m*n,n-1);
            }
        }
    }
    if(flag==1)
         printf("0 0"); 

    return 0;
}

1011 A+B和C

#考察C语言的溢出,不过是正数A + B < A、B了,就说明上溢出
#负数A + B > A、B,就说明下溢出,然而我才不用C语言写呢
#上python,去你娘的C语言溢出嘞

n = int(input())

for i in range(0,n):
  nums = [int(i) for i in input().split(' ')]
  A = nums[0]
  B = nums[1]
  C = nums[2]
  print("Case #{}: {}".format(i+1,"true" if A + B > C else "false"))

1012 数字分类

#有时喜欢def main,有时就直接上了
from decimal import Decimal

input_line = [Decimal(x) for x in input().split(' ')]
num = input_line[0]
input_line = input_line[1:]

exists = [False] * 5

A = [0] * 5
A2_fh = 1
A4_num = 0


for x in input_line:
  if x % 5 == 0:
    if x % 2 == 0:
      A[0] += x
      exists[0] = True
  elif x % 5 == 1:
    exists[1] = True
    A[1] += A2_fh * x
    A2_fh *= -1
  elif x % 5 == 2:
    exists[2] = True
    A[2] += 1
  elif x % 5 == 3:
    exists[3] = True
    A[3] += x
    A4_num += 1
  elif x % 5 == 4:
    exists[4] = True
    if x > A[4]:
      A[4] = x

if exists[3]:      
  A[3] = round(A[3]/A4_num,1)

if exists[0]:
  print(A[0],end="")
else: print("N",end = "")

for i in range(1,5):
  if exists[i]:
    print(" {}".format(A[i]),end = "")
  else:
    print(" N",end = "")

1013 数素数

//按2步进,应该是最优方式了
#include<stdio.h>
#include<math.h>

int is_su(int);

int is_su(int test){

  int bbb = 1;
  for (int i = 3 ; i <= (int)sqrt(test) ; i += 2){   //偶数因子不用测
    if ( !(test % i) )
      bbb = 0;
  }
  return bbb;

}

int main(){

  int begin,end;
  scanf("%d %d",&begin,&end);
  int pos = 1;
  int line = 0;
  if (begin == 1){
    if (end != 1)
      printf("2 ");
    else printf("2");
    line = 1;
  }
  for (int i = 3 ; ; i += 2){
    if (is_su(i)){
      pos += 1;
      if (pos >= begin && pos <= end){
        if (line < 9 && pos != end)
          printf("%d ", i);
        else
          printf("%d\n",i);
        line += 1;
        if (line >= 10) line -= 10;
      }
      if (pos > end) break;
    }
  }

  return 0;
}

1014 福尔摩斯的约会

#有些莫名其妙的坑,简直都懒得去排除,什么玩意
n1=input()
n2=input()
a=[]
b=[chr(x) for x in range(ord("A"),ord("Z")+1)]
c=["MON","TUE","WED","THU","FRI","SAT","SUN"]
for i in range(min(len(n1),len(n2))):
    if "A"<=n1[i]<="G" and n1[i]==n2[i]:
        a.append(n1[i])
        k=i
        break
for i in range(k+1,min(len(n1),len(n2))):
    if "A"<=n1[i]<="N" and n1[i]==n2[i]:
        a.append(str(b.index(n1[i])+10))
        break
    elif "0"<=n1[i]<="9" and n1[i]==n2[i]:
        a.append("0"+n1[i])
        break
m1=input()
m2=input()
for i in range(min(len(m1),len(m2))):
    if ("A"<=m1[i]<="Z" or "a"<=m1[i]<="z") and m1[i]==m2[i]:
        if i<10:
            i="0"+str(i)
        a.append(str(i))
        break
print("%s %s:%s"%(c[b.index(a[0])],a[1],a[2]))

1015 德才论

正确但效率不高的解法

//超时了三个节点,看来还是要用树来保存
//我特么以为超时是需要用树来保存,发现并不是,发现是cin和cout效率太低了

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>

using namespace std;

struct node{
  string ID;
  int de;
  int cai;
  node(const string &s,const int &a ,const int &b):ID(s),de(a),cai(b){};
};

bool be_greater(const node &a ,const node &b){ //a比b大时返回真
  if (a.de + a.cai > b.de + b.cai)
    return true;
  else if (a.de + a.cai < b.de + b.cai)
    return false;
  else if (a.de + a.cai == b.de + b.cai){
    if (a.de > b.de)
      return true;
    else if (a.de < b.de)
      return false;
    else if (a.ID < b.ID)
      return true;
    else return false;
  }
}

void print_res(vector<node> &res){

  for(auto e:res){
    cout << e.ID << " " << e.de << " " << e.cai << endl;
  }

}

int main(){

  int N,L,H;
  cin >> N >> L >> H;
  vector<vector<node>> degree(4,vector<node>());
  int all = 0;

  for (int i = 0 ; i != N ; ++i){
    string ID;
    int de,cai;
    cin >> ID >> de >> cai;
    if (de < L or cai < L){
      continue;
    }else if (de >= H and cai >= H){ //第一类人
      degree[0].push_back(node(ID,de,cai));
      ++all;
    }else if (de >= H and cai < H){
      degree[1].push_back(node(ID,de,cai));
      ++all;
    }else if (de < H and cai < H and de >= cai){
      degree[2].push_back(node(ID,de,cai));
      ++all;
    }else{
      degree[3].push_back(node(ID,de,cai));
      ++all;
    }
  }

  cout << all << endl;

  for(int i = 0 ; i != 4 ; ++i){
    sort(degree[i].begin(),degree[i].end(),be_greater);
    print_res(degree[i]);
  }
  return 0;

}

另一个解法

//发现是cin和cout的锅已经来不及了,我都给换成堆了……
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

struct node
{
  int ID;
  int de;
  int cai;
  node(const int &s, const int &a, const int &b) : ID(s), de(a), cai(b){};
};

struct be_greater
{
  bool operator()( const node &b ,const node &a )
  {
    if (a.de + a.cai > b.de + b.cai)
      return true;
    else if (a.de + a.cai < b.de + b.cai)
      return false;
    else if (a.de + a.cai == b.de + b.cai)
    {
      if (a.de > b.de)
        return true;
      else if (a.de < b.de)
        return false;
      else if (a.ID < b.ID)
        return true;
      else
        return false;
    }
  };
};

using min_heap = priority_queue<node, vector<node>, be_greater>;

void print_res(min_heap &res)
{
  while(!res.empty()){
      auto a = res.top();
      printf("%d %d %d\n",a.ID,a.de,a.cai);
      res.pop();
  }
}

int main()
{

  int N, L, H;
  scanf("%d %d %d",&N,&L,&H);
  vector<min_heap> degree(4);
  int all = 0;

  for (int i = 0; i != N; ++i)
  {
    int ID , de, cai;
    scanf("%d %d %d",&ID,&de,&cai);
    if (de < L or cai < L)
    {
      continue;
    }
    else if (de >= H and cai >= H)
    { //第一类人
      degree[0].push(node(ID, de, cai));
      ++all;
    }
    else if (de >= H and cai < H)
    {
      degree[1].push(node(ID, de, cai));
      ++all;
    }
    else if (de < H and cai < H and de >= cai)
    {
      degree[2].push(node(ID, de, cai));
      ++all;
    }
    else
    {
      degree[3].push(node(ID, de, cai));
      ++all;
    }
  }

  printf("%d\n",all);

  for (int i = 0; i != 4; ++i)
  {
    print_res(degree[i]);
  }
  return 0;
}

针对iostream超时的一些思考

cin慢是有原因的,其实默认的时候,cin与stdin总是保持同步的,也就是说这两种方法可以混用,而不必担心文件指针混乱,同时cout和stdout也一样,两者混用不会输出顺序错乱。正因为这个兼容性的特性,导致cin有许多额外的开销,实际效率差距高达四到五倍。

只需一个语句std::ios::sync_with_stdio(false)禁止这个特性,就可以取消cin于stdin的同步,此时cin的效率和scanf就差不多了。

cin和scanf效率实测

ios::sync_with_stdio(false);

对一切提供文件的函数来说,其实还有一种办法,是用fread()将整个文件一口气全部读入,效率测试比scanf()还要快10倍。

针对c++ callable的一些思考

以下内容截取自《C++Primiere 中文第五版》511页。

C++中有几种可调用的对象:函数、函数指针、lambda表达式,bind创建的对象以及重载了函数调用运算符的类。比如说:

int add(int a,int b){return a + b;};
auto mod = [](int a ,int b) -> int {return a % b;}; //-> int 是lambda的尾置返回值,此例中可省略
struct divide{
    int operator () (int a,int b){
        return a / b;
    }
};
//bind太复杂了这里先不探讨

和其他对象一样,可调用的对象也有类型,比如每个lambda有特自己唯一的(未命名的)类类型,函数及函数指针的类型则由其返回值类型和实参类型决定。需要注意的是,函数和函数指针,其实与其他可调用类型还有所不同,它并不是一个类,因此不能使用在一些要求可调用类的模板中,比如上面的这个例子,priority_queue的定义为:

template <class T, class Container = vector<T>, 
    class Compare = less<typename Container::value_type> > class priority_queue;

第三个参数要求是一个可调用的类型,但传入函数和函数指针就不行,会出错,因此只能像上面那样,创建了一个可调用的类类型:

struct be_greater
{
  bool operator()( const node &b ,const node &a )
  {
    .....
  }
};

然而,两种不同类型的可调用对象却可能共享一种调用形式。调用形式指明了调用返回的类型以及传递给调用的实参类型,一种调用形式对应一个函数类型,例如:

int (int int)

是一个函数类型,接受两个int为参数,返回一个int,比如上面例子中的可调用对象,全部都是这种可调用类型的。

我们有时候可能需要一种更普遍的方式来管理这些可调用对象,比如我们想要把他们放入一个vector里轮番调用的时候,因为他们的各自的类型不同,所以无法放入vector。对于这个问题,我们可以使用C++11引入的function类型来解决这个问题,将所有的类型统一为一个function类型。

function类型这样定义:

#include<functional>
function<int(int,int)> f1 = add;
function<int(int,int)> f2 = mod;
function<int(int,int)> f3 = divide();
//这里的()不是调用的意思,而是构造一个divide类对象,因为divide是一个struct

可惜的是,因为function必须实例化之后才能对应一个可调用对象,因此他也不能传给priority_queue使用,如下的调用是错误的。

#include<functional>

//先定义一个函数
bool be_greater( const node &b ,const node &a ){
    if (a.de + a.cai > b.de + b.cai)
      return true;
    else if (a.de + a.cai < b.de + b.cai)
      return false;
    else if (a.de + a.cai == b.de + b.cai)
    {
      if (a.de > b.de)
        return true;
      else if (a.de < b.de)
        return false;
      else if (a.ID < b.ID)
        return true;
      else
        return false;
    }
}

//用它初始化一个function
function<bool(const node &a,const node &b)> f1 = be_greater;
//把这个function传给priority_queue
using min_heap = priority_queue<node, vector<node>, f1>; //注意,是错误的。

1016 部分A+B

inputline = input().split(' ')

PA = inputline[1] * inputline[0].count(inputline[1])
PB = inputline[3] * inputline[2].count(inputline[3])

print(int(PA or "0") + int(PB or "0"))
#这里的一个小坑,在于如果count的结果是0,那么PA就是空字符串,int("")会出错。所以要or一下
#input一行,其实还可以更简便地写成下面这种形式,这也是python的一个小技巧
a,aa,b,bb = input().split(' ')

1017 A除以B

python的偷懒解法

#用python可以用内置函数超简单地做,如下,但是这道题的边界处理还有点意思,可以考虑用C++划一波
a , b = input().split(' ')
a = int(a)
b = int(b)
q,r = divmod(a,b)

peint(q,r)

C++的正常解法

//C++的解法就要考虑怎么解,很简单的想法就是按正常的除法来借位
//这种基础题最好不要想用什么奇技淫巧,因为往往本来很简单的题,奇技淫巧载在莫名其妙的边界问题上
#include<iostream>
#include<string>

using namespace std;

int main(){

  string a;
  int b;
  cin >> a >> b;
  int lastr = 0;
  //处理一种边界情况,就是第一位就不够除,这时候不能输出0的
  if ( (a[0] - '0') < b){
    lastr = a[0] - '0';
    if (a.size() == 1){
      cout << 0 << " " << a;
      return 0;
    }
  }else{
    cout << (a[0] - '0') / b;
    lastr = (a[0] - '0') % b;
  }

  for ( int i = 1 ; i != a.size() ; ++i){
    cout << (lastr * 10 + (a[i] - '0')) / b;
    lastr = (lastr * 10 + (a[i] - '0')) % b;
  }
  cout << " " << lastr;
  return 0;

}

1018 锤子剪刀布

解法

#include<stdio.h>

#define CHUI 0
#define JIAN 1
#define BU   2
#define WIN 0
#define TIE 1
#define LOSE 2 

int iswinner(char A,char B){
  if (A == 'C' && B == 'J'){
    return 1;
  }else if (A == 'J' && B == 'B'){
    return 1;
  }else if (A == 'B' && B == 'C'){
    return 1;
  }
  return 0;
}

int get_index(char A){
  if (A == 'C')
    return CHUI;
  else if (A == 'J')
    return JIAN;
  else return BU;
}

int max(int a,int b){
  return a > b ? a : b;
}

char get_most_win(int a, int *b){
  if (b[BU] == a)
    return 'B';
  else if (b[CHUI] == a)
    return 'C';
  else return 'J';
}

int main(){

  int N;
  scanf("%d",&N);
  int jiawin[3],yiwin[3];//分别表示甲乙赢的时候CJB的次数,其实可以省略一个,因为倒序输出一次就OK了
  int jiascore[3],yiscore[3]; // 分别表示甲乙胜平负的次数
  for(int i = 0 ; i != 3 ; ++i){
    jiawin[i]   = 0;
    yiwin[i]    = 0;
    jiascore[i] = 0;
    yiscore[i]  = 0;
  }

  char SA[2],SB[2];
  char A,B;

  for (int i = 0 ; i != N ; ++i){
    scanf("%s %s",SA,SB);       //如果直接scanf("%c %c",&A,&B);会出现错误,具体下面详解
    A = SA[0]; B = SB[0];
    if (A == B){
      ++jiascore[TIE];
      ++yiscore[TIE];
    }else if (iswinner(A,B)){
      ++jiawin[get_index(A)];
      ++jiascore[WIN];
      ++yiscore[LOSE];
    }else{
      ++yiwin[get_index(B)];
      ++jiascore[LOSE];
      ++yiscore[WIN];
    }
  }

  printf("%d %d %d\n",jiascore[WIN],jiascore[TIE],jiascore[LOSE]);
  printf("%d %d %d\n",yiscore[WIN],yiscore[TIE],yiscore[LOSE]);
  int maxjia = max(jiawin[CHUI],max(jiawin[JIAN],jiawin[BU]));
  int maxyi = max(yiwin[CHUI],max(yiwin[JIAN],yiwin[BU]));
  printf("%c %c\n",get_most_win(maxjia,jiawin),get_most_win(maxyi,yiwin));

}

关于scanf输入单个字符的问题

如所见,为了输入空格隔开的两个字符,我们用了字符数组,之后再取字符,为什么要这么干呢?为什么要这么干呢?这是因为scanf输入单个字符时存在一些坑。

#include<stdio.h>
int main(){

    char A,B;
    while((scanf("%c%c",&A,&B) != EOF)){
        printf("A=%c B=%c\n",A,B);
    }
    return 0;
}

如上所示的代码,会将字符一个接一个地输入A,B之中,其运行结果如下:

scanf-test-1.png

而如下所示的代码,会将两个c之间的空格解释成间隔符,认为字符是由空格符隔开的,但是因为前后都没有空格,所以会导致第一个输入被解释为由空格符隔开,之后的输入就不是了。结果如下:

#include<stdio.h>
int main(){

    char A,B;
    while((scanf("%c %c",&A,&B) != EOF)){ //在两个%c中间多了一个空格
        printf("A=%c B=%c\n",A,B);
    }
    return 0;
}

上面的代码运行结果如下:

scanf-test-2.png

最后的两行的输出是因为A最后将再读取最后的回车键,而B没有修改,所以会变成这样。究其原因,就是scanf现在是以”%c %c%c %c%c %c%c %c”这样的匹配模式去匹配的,所以上面输入的字符1,2之间的空格被解释为第一个间隔符,但之后第二个%c和第三个%c之间并没有空格,因此A会匹配到一个空格,接下来的第三个%c和第四个%c虽然是空格隔开的,但在输入里由于2后面的空格后面不是空格,因此scanf会忽略这个间隔符,直接把3读入接下来的B,之后一直循环。在最后一次时,A被填写为换行符,但是B没有被覆盖就遇到了EOF,所以B的值没有被覆盖。

要正确处理类似的输入,下面的代码的行为与预期的相同

#include<stdio.h>
int main(){

    char A,B;
    while((scanf("%c %c ",&A,&B) != EOF)){ //在两个%c中间多了一个空格,后面也多了一个空格
  //while((scanf(" %c %c",&A,&B) != EOF)){ //像这样把空格放在前面也行
        printf("A=%c B=%c\n",A,B);
    }
    return 0;
}

结果如下:

scanf-test-3.png

所以关键是将实际的匹配模式修改为”%c %c %c %c %c %c “就行了。

这样其实也不是很保险,所以最好的忽略各种空格的方式,还是例题中写的那样,输入一个%s,之后取其第一个字符。

1019 数字黑洞

x = input()
x = '0' * (4-len(x)) + x    #小坑一个,哈哈。

x1 = "".join(sorted(x,reverse = True))
x2 = "".join(sorted(x))

if (x1 == x2):
  print("{} - {} = 0000".format(x1,x2))
elif (x1 == "7641"):
  print("{} - {} = 6174".format(x1,x2))
else:
  while(x != "6174"):
    x = str(int(x1) - int(x2))
    x = '0' * (4-len(x)) + x  #把0补齐
    print("{} - {} = {}".format(x1,x2,x))
    x1 = "".join(sorted(x,reverse = True))
    x2 = "".join(sorted(x))

1020 月饼

from decimal import Decimal

N,D = [int(x) for x in input().split(' ')]
yuebings = [] #其元素也是数组
kucun = [Decimal(x) for x in input().split(' ')]
zongjia = [Decimal(x) for x in input().split(' ')]
for i in range(0,N):
  yuebings.append([kucun[i],zongjia[i]])

yuebings.sort(key = lambda x:x[1]/x[0],reverse = True)  #按均价排名

xiaoshoue = Decimal(0)

for x in yuebings:
  if D >= x[0]:
    xiaoshoue += x[1]
    D -= x[0]
  else:
    xiaoshoue += x[1] / x[0] * D
    break

print("{:.2f}".format(xiaoshoue))

0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据。