PAT乙级1021-1040

于由astupidcoder发布

乙级的题目就是简单啊……一会会就一道……

1021 个位数统计

in_str = input()
output = [0] * 10
for c in in_str:
  output[int(c)] = output[int(c)] + 1

for i in range(0,10):
  if output[i] != 0:
    print("{}:{}".format(i,output[i]))

1022 D进制的A+B

A,B,radix = [int(x) for x in input().split(' ')]

C = A + B

outstr = ""

if C == 0 :
  print(C)
else:
  while(C != 0):
    C,r = divmod(C,radix)
    outstr = str(r) + outstr
  print(outstr)

1023 组个最小数

line = [int(x) for x in input().split(' ')]

numlist = []
min = 10
for i in range(0,10):
  if line[i] != 0 and i != 0 and i < min:
    min = i
  numlist += [i] * line[i]

numlist.sort()
numlist.remove(min)

print(min,end="")

for x in numlist:
  print(x,end="")

1024 科学计数法

line = input()

if line[0] == '+':
  fuhao = ''
else: fuhao = '-'

line = line[1:]

Epos = line.index('E')
Enum = int(line[Epos + 1:])
num  = line[0:Epos]
num  = num[0:1] + num[2:] #移除.号

if Enum < 0:
  num = "0" * (-1 * Enum) + num
  num = num[0:1] + '.' +  num[1:]
elif Enum >= 0:
  if len(num) - 1 <= Enum:
    num = num + "0" * ( Enum - len(num) + 1 )
  else:
    new_comma_pos = Enum + 1
    num = num[0:new_comma_pos] + '.' + num[new_comma_pos:]

print(fuhao,end = "")
print(num)

1025 翻转链表

正确但超时的算法

//最简单的方法是直接用一个维度100000的数组,直接保存输入,之后再做输出。
//用map也不是不可以,就是更繁琐一点吧。虽然算法无误,但是节点5超时了。

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

using namespace std;

struct node{
  string ptr;
  int data;
  string next_ptr;
  node() = default;
  node(const string &a,const int b,const string &c):ptr(a),data(b),next_ptr(c){}
};

int main(){

  ios::sync_with_stdio(false);
  int origin_head, nodes_num, K;
  cin >> origin_head >> nodes_num >> K;

  vector<node> all_nodes(100000);

  for(int i = 0 ; i != nodes_num ; ++i){
    string a,c;
    int b;
    cin >> a >> b >> c;
    all_nodes[stoi(a)] = node(a,b,c);
  }

  vector<node> link; //模拟一个链表
  int tmp1 = origin_head;
  do{
    link.push_back(all_nodes[tmp1]);
    tmp1 = stoi(all_nodes[tmp1].next_ptr);
  }while(tmp1 != -1);

  nodes_num = link.size();  //有些节点可能是废节点,不入link

  //此时可以开始翻转了,当然是要用算法库了
  int reverse_from = 0;
  while(reverse_from + K <= nodes_num){
    reverse(link.begin() + reverse_from , link.begin() + reverse_from + K);
    reverse_from += K;
  }
  //排完序了,开始输出,这里的正常思路是先把链表建立起来,nextptr都刷对以后再来输出
  //但也可以一次读两个,来偷懒
  for (int i = 0 ; i != nodes_num - 1 ; ++i){
    string next_ptr = link[i+1].ptr;
    cout << link[i].ptr << " " << link[i].data << " " << next_ptr << endl;
  }
  cout << link.back().ptr << " " << link.back().data << " -1" << endl;

  return 0;

}

正确且未超时的算法

//最简单的方法是直接用一个维度100000的数组,直接保存输入,之后再做输出。
//用map也不是不可以,就是更繁琐一点吧。

#include <algorithm>
#include <string>
#include <vector>
#include <cstdio>
//#include<iomanip>

using namespace std;

struct node {
  int ptr;
  int data;
  int next_ptr;
  node() = default;
  node(const int &a, const int &b, const int &c)
      : ptr(a), data(b), next_ptr(c) {}
};

int main() {

  ios::sync_with_stdio(false);
  int origin_head, nodes_num, K;
  scanf("%d %d %d",&origin_head, &nodes_num, &K);

  vector<node> all_nodes(100000);

  for (int i = 0; i != nodes_num; ++i) {
    int a, b, c;
    scanf("%d %d %d",&a, &b, &c);
    all_nodes[a] = node(a, b, c);
  }

  vector<node> link; //模拟一个链表
  int tmp1 = origin_head;
  do {
    link.push_back(all_nodes[tmp1]);
    tmp1 = all_nodes[tmp1].next_ptr;
  } while (tmp1 != -1);

  nodes_num = link.size(); //有些节点可能是废节点,不入link

  //此时可以开始翻转了,当然是要用算法库了
  int reverse_from = 0;
  while (reverse_from + K <= nodes_num) {
    reverse(link.begin() + reverse_from, link.begin() + reverse_from + K);
    reverse_from += K;
  }
  //排完序了,开始输出,这里的正常思路是先把链表建立起来,nextptr都刷对以后再来输出
  //但也可以一次读两个,来偷懒
  for (int i = 0; i != nodes_num - 1; ++i) {
    int ptr;
    int next_ptr;
    ptr = link[i].ptr;
    next_ptr = link[i+1].ptr;
    printf("%05d %d %05d\n",ptr,link[i].data,next_ptr);
    //cout<<setw(5)<<setfill('0')<<ptr<<" "<<link[i].data<<" "<<setw(5)<<setfill('0')<<nextptr<<endl;
  }
  printf("%05d %d -1\n",link.back().ptr,link.back().data);
  //cout<<setw(5)<<setfill('0')<<link.back().ptr<<" "<<link.back().data<<" -1"<<endl;
  //在所有其他地方都一样的情况下,只是修改printf为cout,节点5就超时了,而printf在节点5的运行时间只有106ms
  //可见cout相比printf的巨大效率差,要知道这道题的超时是300ms,也就是说cout的效率低了3倍不止

  return 0;
}

关于超时的一点想法

对于在CPP代码里使用scanf和printf,其实我是拒绝的,但是架不住数据稍大时巨大的效率差,这个效率差我们已经在之前的某一次例题中讲解过了,大概scanf是cin的4倍,这道题告诉我们,printf的效率也是cout的4倍(也可能是因为用了iomanip库反复设置格式的原因,但总之效率不咋地是没跑了)。我用这道题又做了一次测试。

当使用iostream库,关闭stdin同步,用cin输入,printf输出时,节点5的时间是107ms,使用scanf输入,printf输出时,节点5的时间是106ms,可见关闭了stdin同步的cin效率与scanf相差无几。

1016 程序运行时间

CLK_TIK = 100
begin,end = input().split(' ')
ticks = int(end) - int(begin)
seconds = int(ticks/CLK_TIK)    #这里不能用round,原因见下
if ticks % CLK_TIK >= 50:
    seconds += 1
hh = int(seconds / 3600)
seconds -= 3600 * hh
mm = int( seconds / 60)
seconds -= 60 * mm
ss = seconds

hh = str(hh) if hh > 10 else '0' + str(hh)
mm = str(mm) if mm > 10 else '0' + str(mm)
ss = str(ss) if ss > 10 else '0' + str(ss)

print(hh+":"+mm+":"+ss)

python的round函数

不啰嗦,直接上图:

python-round.png

可见当小数位刚好为0.5时,会向偶数取整,而不是四舍五入。

1027 打印沙漏

num,c = input().split()
num = int(num)


if num < 7:   #只够输出一行
  print(c)
  print(num - 1)
else:
  max_line = 3  #一行最多输出几个字符,从3起算
  used = 1
  while used + max_line * 2 <= num:
    used += max_line * 2
    max_line += 2
  max_line -= 2 #前面加多了……
  tmp = max_line
  blanknum = 0
  while tmp != 1:
    print(" " * blanknum + c * tmp)
    blanknum += 1
    tmp -= 2
  while tmp <= max_line:
    print(" " * blanknum + c * tmp)
    blanknum -= 1
    tmp += 2
  print(num - used)

1028 人口普查

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

int isolder(int ayy, int amm, int add, int byy, int bmm, int bdd) {
  if (ayy < byy || (ayy == byy && amm < bmm) ||
      (ayy == byy && amm == bmm && add < bdd))
    return 1;
  else
    return 0;
}

int isyounger(int ayy, int amm, int add, int byy, int bmm, int bdd) {
  return isolder(byy, bmm, bdd, ayy, amm, add);
}

int birthday_ok(int a, int b, int c) {
  if (a < 1814 || (a == 1814 && b < 9) || (a == 1814 && b == 9 && c < 6))
    return 0;
  if (a > 2014 || (a == 2014 && b > 9) || (a == 2014 && b == 9 && c > 6))
    return 0;
  return 1;
}

int main() {

  char oldest[6], youngest[6], now[6];
  int oldyy = 2018, oldmm = 7, olddd = 13;
  int youngyy = 1800, youngmm = 7, youngdd = 13;
  int nums, legal = 0;
  scanf("%d", &nums);
  for (int i = 0; i != nums; ++i) {
    int nowyy, nowmm, nowdd;
    scanf("%s %d/%d/%d", now, &nowyy, &nowmm, &nowdd);
    if (birthday_ok(nowyy, nowmm, nowdd)) {
      legal++;
      if (isolder(nowyy, nowmm, nowdd, oldyy, oldmm, olddd)) {
        strcpy(oldest,now);
        oldyy = nowyy;
        oldmm = nowmm;
        olddd = nowdd;
      }
      if (isyounger(nowyy, nowmm, nowdd, youngyy, youngmm, youngdd)) {
        strcpy(youngest,now);
        youngyy = nowyy;
        youngmm = nowmm;
        youngdd = nowdd;
      }
    }
  }
  if (legal != 0)       //否则某节点会格式错误
    printf("%d %s %s",legal,oldest,youngest);
  else
    printf("0");
  return 0;
}

1029 坏键盘

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

using namespace std;

int main() {

  string a, b;
  cin >> a >> b;
  transform(a.begin(), a.end(), a.begin(), ::toupper);
  transform(b.begin(), b.end(), b.begin(), ::toupper);
  string output;
  for (auto c : a) {
    if (b.find(c) == string::npos && output.find(c) == string::npos){
      output += c;
    }
  }
  cout << output << endl;
  return 0;
}

1030 完美数列

//本来,看到这道题可能隐含一个大数相乘的坑,当时我就想用python
//想不到,完全相同的逻辑,用python竟然会300ms超时……而用c++只用了37ms……
#include<cstdio>
#include<vector>
#include<algorithm>
#include<limits>

#define INT_MAX numeric_limits<int>::max()

using namespace std;

int main(){

  int N,p;
  scanf("%d %d",&N,&p);
  vector<int> list(N);

  for(int i = 0 ; i != N ; ++i)
    scanf("%d",&list[i]);

  sort(list.begin(),list.end());
  int last = 0;
  int maxlen = 0;

  for (int i = 0 ; i != N ; ++i ){
    int j;
    if (INT_MAX / list[i] < p){     //可能出现大数相乘,超过int界限,因此这里用除法做个判断
      maxlen = N - i;
      break;
    }
    for (j = last ; j != N ; ++j){
      if (list[j] > list[i] * p ){
        last = j - 1;
        break;
      }
      //程序如果到了这里退出循环,说明最后一个数都小
      last = j;
    }
    if (last - i + 1 > maxlen)
      maxlen = last - i + 1;
    if (last == N - 1)  //进一步优化速度,当last已经到最后一位时,就没有继续的必要了
      break;
  }

  printf("%d\n",maxlen);
  return 0;

}

1031 查验身份证

def is_not_ok(c):
  quan = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
  map  = [1,0,10,9,8,7,6,5,4,3,2]
  head = c[:17]
  tail = int(c[17]) if c[17].isdigit() else 10
  if head.isdigit() != True:
    return True;
  res = 0
  for i in range(0,17):
    res += int(head[i]) * quan[i]

  res = map[res%11]
  if res == int(tail):
    return False
  else: return True

def main():
  N = int(input())

  output = []

  for i in range(0,N):
    c = input();
    if is_not_ok(c):
      output.append(c)

  if len(output) == 0:
    print("All passed")
  else:
    for c in output:
      print(c)

if __name__=="__main__":
    main()

1032 挖掘机技术哪家强

#include<map>
#include<iostream>

using namespace std;

int main(){

  ios::sync_with_stdio(false);
  int N;
  cin >> N;
  map<int,int> score_sum;
  int max_snum = -1 ,max_score = 0;
  for(int i = 0 ; i != N ; ++i){
    int snum,score;
    cin >> snum >> score;
    score_sum[snum] += score;
    if (score_sum[snum] > max_score){
      max_score = score_sum[snum];
      max_snum = snum;
    }
  }

  cout << max_snum << " " << max_score << endl;
  return 0;

}

1033 旧键盘打字

超时解法

//第二行直接用getchar好了
//超时原因待排查,初步估计不是cin的锅,而是string的find函数比较低效
//果然不是cin的锅,看来得上set了

#include <iostream>
#include <string>

using namespace std;

int main() {

  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  string broken;
  cin >> broken;
  cin.get(); //跳过换行符
  bool CAP_broken = false;

  if (broken.find('+') != string::npos) {
    CAP_broken = true;
  }
  char c;
  while ((c = cin.get()) != '\n') {
    if (isupper(c) && CAP_broken) {
      ; //啥都不做
    } else {
      if (broken.find(toupper(c)) == string::npos) {
        cout << c;
      }
    }
  }

}

不超时解法

//第二行直接用getchar好了
//超时原因待排查,初步估计不是cin的锅,而是string的find函数比较低效
//果然不是cin的锅,看来得上set了

#include <iostream>
#include <set>

using namespace std;

int main() {

  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  char c;
  set<char> broken;
  while((c = cin.get()) != '\n'){
    broken.insert(c);
  }

  bool CAP_broken = false;

  if (broken.find('+') != broken.end()) {
    CAP_broken = true;
  }
  while ((c = cin.get()) != '\n') {
    if (isupper(c) && CAP_broken) {
      ; //啥都不做
    } else {
      if (broken.find(toupper(c)) == broken.end()) {
        cout << c;
      }
    }
  }

}

时间对比

pat-b-1033-2.png

pat-b-1033-1.png

唔……只有节点3有区别,为毛啊?

1034 有理数四则运算

C++解法

#include<iostream>
#include<string>

using namespace std;

int zuidagongyueshu(long a, long b) {

    int i = 0;
    if (a == 0 || b == 0)
        return 1;
    /*for (i = min; ; --i) {//这样一个数一个数减下去,确实效率不高
        if (!(a % i) && !(b % i))
            break;
    }*/
    int c;
    while (true) {
        if ( ( c = a % b ) == 0)
            return b;
        else { a = b; b = c; }
    }
    return 1;

}


void getoper(long &up, long &down,string & ss){

    if (up == 0 || down == 0) {
        ss = '0';
        return;
    }

    if (down < 0) {
        down = 0 - down;
        up = 0 - up;
    }

    int zuida = zuidagongyueshu(up, down);
    if (zuida < 0) zuida = 0 - zuida;

    up /= zuida; down /= zuida;
    int int1 = up / down;
    int up11 = up - down * int1;

    if (int1 != 0) {
        ss += std::to_string(int1) + " ";
    }

    if (int1  < 0) {
        up11 = up11 >= 0 ? up11 : 0 - up11;
    }

    if (up11 != 0)
        ss = ss + std::to_string(up11) + '/' + std::to_string(down);
    else ss.pop_back();

    if (int1 < 0 || up11 < 0)
        ss = '(' + ss + ')';

}


int main() {

    //坑在于,一个是虽然输入的数都是int,但是相乘后可能超出int,所以要用long
    //另一个坑就要用整型最大值去测试了,很烦人的
    //另一个坑是,我做了很多取负值的计算,假如值为Tmin,就出错

    string a, b;
    cin >> a >> b;
    long up1 = std::stoi(a.substr(0, a.find('/'))), down1 = std::stoi(a.substr(a.find('/') + 1));
    long up2 = std::stoi(b.substr(0, b.find('/'))), down2 = std::stoi(b.substr(b.find('/') + 1));

    string oper1, oper2;

    getoper(up1, down1,oper1);
    getoper(up2, down2,oper2);

    long result_up1 = up1 * down2 + up2 * down1, result_down1 = down1 * down2;
    long result_up2 = up1 * down2 - up2 * down1, result_down2 = down1 * down2;
    long result_up3 = up1 * up2 , result_down3 = down1 * down2;
    long result_up4 = up1 * down2, result_down4 = up2 * down1;

    string r1, r2, r3, r4;

    getoper(result_up1, result_down1,r1);
    getoper(result_up2, result_down2,r2);
    getoper(result_up3, result_down3,r3);
    if (oper2 == "0")
        r4 = "Inf";
    else getoper(result_up4, result_down4,r4);

    cout << oper1 << " + " << oper2 << " = " << r1 << endl;
    cout << oper1 << " - " << oper2 << " = " << r2 << endl;
    cout << oper1 << " * " << oper2 << " = " << r3 << endl;
    cout << oper1 << " / " << oper2 << " = " << r4 << endl;

    return 0;
}

python解法

#fractions 模块有不少好用的功能,比如说gcd,求最大公约数的
#Fraction 会自动将分子分母最大公约掉

def get_str(a):
  """
  将一个Fraction转换为一个字符串
  """
  aup = a.numerator
  adown = a.denominator
  negative = False
  if aup < 0:
    negative = True
    aup = -aup

  if aup == 0:
    ret = '0'
  elif aup % adown == 0:
    ret = str(int(aup / adown))
  else:
    int_part = int(aup / adown)
    aup -= int_part * adown
    if int_part == 0:
      ret = str(aup) + '/' + str(adown)
    else:
      ret = str(int_part) + " " + str(aup) + '/' + str(adown)

  if negative:
    ret = "(-" + ret + ")"

  return ret

def main():
  from fractions import Fraction, gcd
  a, b = input().split()
  a = Fraction(a)
  b = Fraction(b)
  print("{} + {} = {}".format(get_str(a), get_str(b), get_str(a+b)))
  print("{} - {} = {}".format(get_str(a), get_str(b), get_str(a-b)))
  print("{} * {} = {}".format(get_str(a), get_str(b), get_str(a*b)))
  if b != 0:
    print("{} / {} = {}".format(get_str(a), get_str(b), get_str(a/b)))
  else:
    print("{} / {} = Inf".format(get_str(a), get_str(b)))

if __name__=="__main__":
  main()

1035 插入与归并

//想不来怎么判断,不如直接实现插入和归并算法,一步一步求呗

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

using namespace std;

void insert(const vector<int> &origin, vector<int> &next_step, int sorted_num);
void merge(const vector<int> &origin, vector<int> &next_step, int length);

int main() {

  ios::sync_with_stdio(false);
  int N;
  cin >> N;
  vector<int> origin(N);
  vector<int> half(N);
  for (int i = 0; i != N; ++i) {
    cin >> origin[i];
  }

  for (int i = 0; i != N; ++i) {
    cin >> half[i];
  }
  vector<int> next_step;
  for(int i = 0 ; i != N ; ++i){
    insert(origin,next_step,i);
    if (next_step == half){
      cout << "Insertion Sort" << endl;
      while(next_step == half)  //这个while的意义下述
        insert(origin,next_step,++i);
      for(int j = 0 ; j != N - 1; ++j)
        cout << next_step[j] << " ";
      cout << next_step.back() << endl;
      return 0;
    }
  }
  next_step = origin;
  int length = 2;
  while(true){
    merge(origin,next_step,length);
    length *= 2;
    if (next_step == half){
      cout << "Merge Sort" << endl;
      merge(origin,next_step,length);
      for(int j = 0 ; j != N - 1; ++j)
        cout << next_step[j] << " ";
      cout << next_step.back() << endl;
      return 0;
    }
  }

}

void insert(const vector<int> &origin, vector<int> &next_step, int index) {

  int tmp = origin[index];
  next_step.erase(next_step.begin() + index , next_step.end());
  int size = next_step.size();
  for (int i = 0; i != size; ++i) {
    if (tmp < next_step[i]) {
      next_step.insert(next_step.begin() + i, tmp);
      break;
    }
  }

  if (next_step.size() == size) { //并没有插入,说明tmp最大
    next_step.push_back(tmp);
  }
  next_step.insert(next_step.end(),origin.begin() + index + 1 , origin.end());

}

void merge(const vector<int> &origin, vector<int> &next_step, int length) {

  int i;
  if (length >= origin.size()) {
    sort(next_step.begin(), next_step.end());
  } else {
    for (i = 0; i <= origin.size() - length; i += length) {
      sort(next_step.begin() + i, next_step.begin() + i + length);
    }
    if ( i != origin.size())
      sort(next_step.begin() + i , next_step.end());
  }
}

while循环的意义

有时候,插入算法在将一个新值纳入考虑时,并不会改变数列的顺序,比如

10
3 1 2 8 7 5 9 4 6 0
插入排序到第6个元素,"5"之后,得到以下数列:
1 2 3 5 7 8 9 4 6 0
当纳入第7个元素"9"之后,
数列是不变的,这就出问题了。

1036 跟奥巴马一起编程

#include<iostream>

using namespace std;

int main() {

    int k;
    char c;
    cin >> k >> c;

    for (int i = 0; i != (k+1)/2; ++i) {
        for (int j = 0; j != k; ++j) {
            if (i == 0 || i == (k - 1) / 2 || j == 0 || j == k - 1)
                cout << c;
            else cout << " ";
        }
        cout << endl;
    }
    return 0;
}

1037 在霍格沃兹找零钱

Price,Paid = input().split()

PG,PS,PK = [int(x) for x in Price.split('.')]
AG,AS,AK = [int(x) for x in Paid.split('.')]

PKS = PG * 29 * 17 + PS * 29 + PK
AKS = AG * 29 * 17 + AS * 29 + AK

back = AKS - PKS

if back < 0:
  back = -back
  negative = "-"
else:
  negative = ""

backG = int(back / (29 * 17))
backS = int((back % (29 * 17)) / 29)
backK = back % 29

print(negative + str(backG) + '.' + str(backS) + '.' + str(backK));

1038 统计同成绩学生

#include<map>
#include<iostream>

using namespace std;

int main(){

  ios::sync_with_stdio(false);
  cin.tie(nullptr); //不加这句话,这种算法会超时
  int s;
  int N;
  cin >> N;
  map<int,int> scores;
  for( int i = 0 ; i != N ; ++i){
    cin >> s;
    ++scores[s];
  }
  cin >> N;
  for(int i = 0 ; i != N - 1 ; ++i){
    cin >> s;
    cout << scores[s] << " ";
  }
  cin >> N;
  cout << scores[N] << endl;
  return 0;

}

再谈iostream的效率问题

为了下面说明的方便,我们在这里再推出一种算法:

#include<iostream>
#include<map>
#include<vector>

using namespace std;

int main() {

    int k1;
    int score;
    int k2;
    vector<int> results;
    map<int, int> score_store;

    cin >> k1;
    while (k1--) {
        cin >> score;
        ++score_store[score];
    }
    cin >> k2;
    while (k2--) {
        cin >> score;
        results.push_back(score_store[score]);
    }

    for (auto it = results.begin(); it != results.end() - 1; ++it)
        cout << *it << " ";
    cout << results.back();

    return 0;

}

与之前的算法基本相同,只是将结果收集到vector里,然后再输出。也就是说cin和cout不是像算法一里面那样交叉使用了,而是先cin完再cout。这就涉及到效率问题了。

ios::sync_with_stdio(false)的效率我们已经讨论过了,在算法二中,仅仅添加该语句,就将时间从125ms降到了54ms,不做详细讨论,在此只讨论cin.tie(nullptr)的问题。

在算法1中,没有cin.tie(nullptr),大节点直接超时(250ms),而加上的话只有56ms。在算法2中,没有的话大节点是54ms,有了是53ms,应该属于没有差异。

可见,在cin和cout交替调用的时候,cin.tie(nullptr)能带来很大的效率提升,但为什么cin要和cout绑定呢?

在《C++ Premiere 5th》P282中提到:

当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流。标准库将cout与cin关联到一起,因此每次调用cin>>val;都会导致cout的缓冲区被刷新。

交互式系统通常应该关联输入流和输出流,这意味着所有输出,包括用户提示信息,都会在读操作之前被打印出来。

也就是说,关联这两个流之后,cin会不断刷新cout的缓冲区,也就是直接调用系统调用去实现IO操作了,交替使用当然效率惨不忍睹,但好处是这样不会导致输入输出混乱。否则下面的代码:

cin.tie(nullptr);
cout << "Input:";
cin >> val;

有可能在cout刷新缓存,Input:真正被写到控制台之前就提示输入了。但只是有可能,实际情况仍然取决于具体实现。

1039 到底买不买

//还以为是最长公共子序列,原来简单多了
//当然是换一家淘宝店买了

#include<iostream>
#include<map>

using namespace std;

int main(){

  ios::sync_with_stdio(false);
  char c;
  map<char,int> get,want;
  bool sufficient = true;
  int gets = 0 , wants = 0;
  while( (c = cin.get() ) != '\n'){
    ++get;
    ++gets;
  }
  while( (c = cin.get() ) != '\n'){
    ++want;
    ++wants;
  }
  int miss = 0;
  for (auto it = want.begin() ; it != want.end() ; ++it){
    if (get[it->first] < it->second){
      sufficient = false;
      miss += it->second - get[it->first];
    }
  }

  if (sufficient){
    cout << "Yes " << gets - wants << endl;
  }else{
    cout << "No " << miss << endl;
  }

  return 0;

}

1040 有几个PAT

//所以这道题想干嘛??
#include<stdio.h>

int main(){

  long long Pnum = 0 , PAnum = 0 , total = 0;
  char c;
  while((c = getchar()) != '\n'){
    switch(c){
      case 'P':
        ++Pnum;
        break;
      case 'A':
        PAnum += Pnum;
        break;
      case 'T':
        total += PAnum;
        total %= 1000000007;
    }
  }

  printf("%d\n",total);
  return 0;

}

0 条评论

发表回复

Avatar placeholder

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

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