HDU100题简要题解(2090~2099)

HDU2090 算菜价

题目链接

Problem Description
妈妈每天都要出去买菜,但是回来后,兜里的钱也懒得数一数,到底花了多少钱真是一笔糊涂帐。现在好了,作为好儿子(女儿)的你可以给她用程序算一下了,呵呵。

Input
输入含有一些数据组,每组数据包括菜种(字串),数量(计量单位不论,一律为double型数)和单价(double型数,表示人民币元数),因此,每组数据的菜价就是数量乘上单价啊。菜种、数量和单价之间都有空格隔开的。

Output
支付菜价的时候,由于最小支付单位是角,所以总是在支付的时候采用四舍五入的方法把分头去掉。最后,请输出一个精度为角的菜价总量。

Sample Input
青菜 1 2
罗卜 2 1.5
鸡腿 2 4.2

Sample Output
13.4

水题,直接算,无坑

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;

double a, b, ans = 0;
string s;

int main() {
  ios::sync_with_stdio(false);
  while (cin >> s >> a >> b) 
    ans += (a * b);
  printf("%.1lf\n", ans);
  return 0;
}

HDU2091 空心三角形

题目链接

Problem Description
把一个字符三角形掏空,就能节省材料成本,减轻重量,但关键是为了追求另一种视觉效果。在设计的过程中,需要给出各种花纹的材料和大小尺寸的三角形样板,通过电脑临时做出来,以便看看效果。

Input
每行包含一个字符和一个整数n(0<n<41),不同的字符表示不同的花纹,整数n表示等腰三角形的高。显然其底边长为2n-1。如果遇到@字符,则表示所做出来的样板三角形已经够了。

Output
每个样板三角形之间应空上一行,三角形的中间为空。显然行末没有多余的空格。

Sample Input
X 2
A 7
@

Sample Output

 X
XXX
 
      A
     A A
    A   A
   A     A
  A       A
 A         A
AAAAAAAAAAAAA

模拟题,但是一定要注意一下输出格式:每一行后面无多余空格,每个数据之间有换行但是最后没有
一开始没注意到这些地方PE了五六次...

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

int n, cnt;
char c;

int main() {
  ios::sync_with_stdio(false);
  int flag = 0;
  while (cin >> c) {
    if (c == '@') break;
    if (flag != 0) cout << endl;
    flag = 1;
    cin >> n;
    cnt = n - 1;
    for (int i = 1; i <= n; i++) {
      if (i == 1) {    //第一行
  	for (int j = 1; j <= cnt; j++) cout << " ";
  	cout << c;
  	cnt--;
  	cout << endl;
  	continue;
      }
      if (i == n) {    //最后一行
  	for (int j = 1; j <= n * 2 - 1; j++) cout << c;
  	cout << endl;
  	continue;
      }
      for (int j = 1; j <= cnt; j++) cout << " ";     // 中间部分每一行前面的空格
      cout << c;
      for (int j = 1; j <= 2 * i - 3; j++) cout << " ";     //中间部分每一行中间的空格
      cout << c;
      cnt--;
      cout << endl;
    }
  }
  return 0;
}

HDU2092 整数解

题目链接

Problem Description
有二个整数,它们加起来等于某个整数,乘起来又等于另一个整数,它们到底是真还是假,也就是这种整数到底存不存在,实在有点吃不准,你能快速回答吗?看来只能通过编程。
例如:
x + y = 9,x * y = 15 ? 找不到这样的整数x和y
1+4=5,14=4,所以,加起来等于5,乘起来等于4的二个整数为1和4
7+(-8)=-1,7
(-8)=-56,所以,加起来等于-1,乘起来等于-56的二个整数为7和-8

Input
输入数据为成对出现的整数n,m(-10000<n,m<10000),它们分别表示整数的和与积,如果两者都为0,则输入结束。

Output
只需要对于每个n和m,输出“Yes”或者“No”,明确有还是没有这种整数就行了。

Sample Input
9 15
5 4
1 -56
0 0

Sample Output
No
Yes
Yes

直接暴力枚举

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

int n, m;

int main() {
  ios::sync_with_stdio(false);
  while (cin >> n >> m) {
    int flag = 0;
    if (n == 0 && m == 0) break;
    for (int i = -abs(m); i <= abs(m); i++)
      if (i * (n - i) == m) {
      	flag = 1;
      	break;
      }
    if (flag == 0) cout << "No" << endl;
    else cout << "Yes" << endl;
  }
  return 0;
}

HDU2093 考试排名

题目链接

Problem Description
C++编程考试使用的实时提交系统,具有即时获得成绩排名的特点。它的功能是怎么实现的呢?
我们做好了题目的解答,提交之后,要么“AC”,要么错误,不管怎样错法,总是给你记上一笔,表明你曾经有过一次错误提交,因而当你一旦提交该题“AC”后,就要与你算一算帐了,总共该题错误提交了几回。虽然你在题数上,大步地跃上了一个台阶,但是在耗时上要摊上你共花去的时间。特别是,曾经有过的错误提交,每次都要摊上一定的单位时间分。这样一来,你在做出的题数上,可能领先别人很多,但是,在做出同样题数的人群中,你可能会在耗时上处于排名的劣势。
例如:某次考试一共8题(A,B,C,D,E,F,G,H),每个人做的题都在对应的题号下有个数量标记,负数表示该学生在该题上有过的错误提交次数,但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上一对括号,里面有个整数b,那就表示该学生提交该题AC了,耗去了时间a,同时,曾经错误提交了b次,因此对于下述输入数据:

若每次错误提交的罚分为20分,则其排名从高到低应该是这样的:
Josephus 5 376
John 4 284
Alice 4 352
Smith 3 167
Bob 2 325
Bush 0 0

Input
输入数据的第一行是考试题数n(1≤n≤12)以及单位罚分数m(10≤m≤20),每行数据描述一个学生的用户名(不多于10个字符的字串)以及对所有n道题的答题现状,其描述采用问题描述中的数量标记的格式,见上面的表格,提交次数总是小于100,AC所耗时间总是小于1000。

Output
将这些学生的考试现状,输出一个实时排名。实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。

Sample Input
8 20
Smith	  -1	-16	8	0	0	120	39	0
John	  116	-2	11	0	0	82	55(1)	0
Josephus  72(3)	126	10	-3	0	47	21(2)	-2
Bush	  0	-1	-8	0	0	0	0	0
Alice	  -2	67(2)	13	-1	0	133	79(1)	-1
Bob	  0	0	57(5)	0	0	168	-7	0
 
Sample Output
Josephus    5  376
John        4  284
Alice       4  352
Smith       3  167
Bob         2  325
Bush        0    0

一开始没看懂题...拿着计算器敲了好久才明白啥意思,计算的时候就不断提取出每个题目的数字,是正数的话就加起来,然后看看有无括号,有的话就再算上括号里的

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

int n, m, cnt;
string name, s;
struct node{
  string name;
  int sum;
  int time;
}a[1001];

inline bool cmp(node x, node y) {
  if (x.sum != y.sum) return x.sum > y.sum;
  else if (x.time != y.time) return x.time < y.time;
  else return x.name < y.name;
}

int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m;
  while (cin >> name) {
    cnt++;
    a[cnt].name = name;
    a[cnt].sum = 0;
    a[cnt].time = 0;
    for (int i = 1; i <= n; i++) {
      cin >> s;
      if (s[0] == '-' || s[0] == '0') continue;
      int num;
      sscanf(s.c_str(), "%d", &num);
      a[cnt].sum++;
      a[cnt].time += num;
      int pos = s.find('(');
      if (pos != string::npos) {
  	sscanf(s.c_str() + pos + 1, "%d", &num);
  	a[cnt].time += (num * m);
      }
    }
  }
  sort(a + 1, a + 1 + cnt, cmp);
  for (int i = 1; i <= cnt; i++) 
    printf("%-10s %2d %4d\n", a[i].name.c_str(), a[i].sum, a[i].time);
  return 0;
}

HDU2094 产生冠军

题目链接

Problem Description
有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛。
球赛的规则如下:
如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。
如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。
根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。

Input
输入含有一些选手群,每群选手都以一个整数n(n<1000)开头,后跟n对选手的比赛结果,比赛结果以一对选手名字(中间隔一空格)表示,前者战胜后者。如果n为0,则表示输入结束。

Output
对于每个选手群,若你判断出产生了冠军,则在一行中输出“Yes”,否则在一行中输出“No”。

Sample Input
3
Alice Bob
Smith John
Alice Smith
5
a c
c d
d e
b e
a d
0

Sample Output
Yes
No

看看有几个点的vis是0即可,超过一个那么就是no

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

int n, ans, vis[1001];
string s1, s2;
map<string, int> a;

int main() {
  ios::sync_with_stdio(false);
  while (cin >> n) {
    if (n == 0) break;
    ans = 0;
    a.clear();
    memset(vis, 0, sizeof(vis));
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
      cin >> s1 >> s2;
      if (a[s1] == 0) a[s1] = ++cnt;
      if (a[s2] == 0) a[s2] = ++cnt;
      vis[a[s2]]++;
    }
    for (int i = 1; i <= cnt; i++)
      if (vis[i] == 0) ans++;
    if (ans != 1) cout << "No" << endl;
    else cout << "Yes" << endl;
  }
  return 0;
}

HDU2095 find your present (2)

题目链接

Problem Description
In the new year party, everybody will get a "special present".Now it's your turn to get your special present, a lot of presents now putting on the desk, and only one of them will be yours.Each present has a card number on it, and your present's card number will be the one that different from all the others, and you can assume that only one number appear odd times.For example, there are 5 present, and their card numbers are 1, 2, 3, 2, 1.so your present will be the one with the card number of 3, because 3 is the number that different from all the others.

Input
The input file will consist of several cases.
Each case will be presented by an integer n (1<=n<1000000, and n is odd) at first. Following that, n positive integers will be given in a line, all integers will smaller than 2^31. These numbers indicate the card numbers of the presents.n = 0 ends the input.

Output
For each case, output an integer in a line, which is the card number of your present.

Sample Input
5
1 1 3 2 2
3
1 2 1
0

Sample Output
3
2
Hint
use scanf to avoid Time Limit Exceeded

做这题之前刚在洛谷上做了一个几乎一模一样的题 p1469找筷子
一开始用map做的,结果MLE了6个点,所以想到了使用异或
关于异或呢,它有两个特点:
1、奇数个相同的数异或结果为其本身,偶数个相同的数异或结果为0
2、任何数与0异或结果是它本身
所以很明显此题用异或做十分方便

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

int n, x, ans;

int main() {
  ios::sync_with_stdio(false);
  while (cin >> n) {
    if (n == 0) break;
    ans = 0;
    for (int i = 1; i <= n; i++) {
      cin >> x;
      ans ^= x;
    }
    cout << ans << endl;
  }
  return 0;
}

HDU2096 小明A+B

题目链接

Problem Description
小明今年3岁了, 现在他已经能够认识100以内的非负整数, 并且能够进行100以内的非负整数的加法计算.
对于大于等于100的整数, 小明仅保留该数的最后两位进行计算, 如果计算结果大于等于100, 那么小明也仅保留计算结果的最后两位.
例如, 对于小明来说:
1、1234和34是相等的
2、35+80=15
给定非负整数A和B, 你的任务是代表小明计算出A+B的值.

Input
输入数据的第一行为一个正整数T, 表示测试数据的组数. 然后是T组测试数据. 每组测试数据包含两个非负整数A和B(A和B均在int型可表示的范围内).

Output
对于每组测试数据, 输出小明A+B的结果.

Sample Input
2
35 80
15 1152

Sample Output
15
67

只取最后两位,大于100了就处理一下

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

int t, a, b, ans;

int main() {
  ios::sync_with_stdio(false);
  cin >> t;
  while(t--) {
    cin >> a >> b;
    if (a >= 100) {
      int num1 = a % 10;
      a /= 10;
      int num2 = a % 10;
      a = num2 * 10 + num1;
    }
    if (b >= 100) {
      int num1 = b % 10;
      b /= 10;
      int num2 = b % 10;
      b = num2 * 10 + num1;
    }
    ans = a + b;
    if (ans >= 100) {
      int num1 = ans % 10;
      ans /= 10;
      int num2 = ans % 10;
      ans = num2 * 10 + num1;
    }
    cout << ans << endl;
  }
  return 0;
}

HDU2097 Sky数

题目链接

Problem Description
Sky从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992,这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22,同时它的十二进制数表示1894,其四位数字之和也为22,啊哈,真是巧啊。Sky非常喜欢这种四位数,由于他的发现,所以这里我们命名其为Sky数。但是要判断这样的数还是有点麻烦啊,那么现在请你帮忙来判断任何一个十进制的四位数,是不是Sky数吧。

Input
输入含有一些四位正整数,如果为0,则输入结束。

Output
若n为Sky数,则输出“#n is a Sky Number.”,否则输出“#n is not a Sky Number.”。每个结果占一行。注意:#n表示所读入的n值。

Sample Input
2992
1234
0

Sample Output
2992 is a Sky Number.
1234 is not a Sky Number.

不要想象的太复杂,算出每个进制的每一位相加就可以

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

int n;

inline bool check(int x) {
  int cnt1 = 0;
  int cnt2 = 0;
  int cnt3 = 0;
  int num = x;
  while (num) {
    cnt1 += num % 10;
    num /= 10;
  }
  num = x;
  while (num) {
    cnt2 += num % 12;
    num /= 12;
  }
  num = x;
  while (num) {
    cnt3 += num % 16;
    num /= 16;
  }
  if (cnt1 == cnt2 && cnt1 == cnt3 && cnt2 == cnt3) return true;
  return false;
}

int main() {
  ios::sync_with_stdio(false);
  while (cin >> n) {
    if (n == 0) break;
    if (check(n)) printf("%d is a Sky Number.\n", n);
    else printf("%d is not a Sky Number.\n", n);
  }
  return 0;
}

HDU2098 分拆素数和

题目链接

Problem Description
把一个偶数拆成两个不同素数的和,有几种拆法呢?

Input
输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束。

Output
对应每个偶数,输出其拆成不同素数的个数,每个结果占一行。

Sample Input
30
26
0

Sample Output
3
2

直接暴力上!枚举两个数,判断两个数是不是都为素数就好了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

int x, y, ans;

inline bool isprime(int num) {
  if (num == 2) return true;
  for (int i = 2; i <= num / 2; i++)
    if (num % i == 0) return false;
  return true;
}

inline bool check(int a, int b) {
  if (isprime(a) && isprime(b)) return true;
  return false;
}

int main() {
  ios::sync_with_stdio(false);
  while (cin >> x) {
    ans = 0;
    if (x == 0) break;
    for (int i = 2; i <= x / 2; i++) {
      y = x - i;
      if (i == y) continue;
      if (check(i, y)) ans++;
    }
    cout << ans << endl;
  }
  return 0;
}

HDU2099 整除的尾数

题目链接

Problem Description
一个整数,只知道前几位,不知道末二位,被另一个整数除尽了,那么该数的末二位该是什么呢?

Input
输入数据有若干组,每组数据包含二个整数a,b(0<a<10000, 10<b<100),若遇到0 0则处理结束。

Output
对应每组数据,将满足条件的所有尾数在一行内输出,格式见样本输出。同组数据的输出,其每个尾数之间空一格,行末没有空格。

Sample Input
200 40
1992 95
0 0

Sample Output
00 40 80
15

暴力枚举

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

int a, b;

int main() {
  ios::sync_with_stdio(false);
  while (cin >> a >> b) {
    int flag = 0;
    if (a == 0 && b == 0) break;
    a *= 100;
    for (int i = 0; i < 100; i++) {
      if ((a + i) % b == 0) {
        if (flag == 1) printf(" ");
  	flag = 1;
  	printf("%02d", i);
      }
    }
    printf("\n");
  }
  return 0;
}

由于好奇是否还有更好的解法,去搜了题解发现了一个数学办法,强,佩服大佬

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

int a, b;

int main() {
  ios::sync_with_stdio(false);
  while (cin >> a >> b) {
    if (a == 0 && b == 0) break;
    int num = (b - a * 100 % b) % b;
    for (int i = num; i < 100; i += b) {
      if (i != num) printf(" ");
      printf("%02d", i);
    }
    printf("\n");
  }
  return 0;
}

完结撒花~接下来短时间内可以多去搞搞CTF啦()

posted @ 2020-11-23 22:33  Moominn  阅读(513)  评论(0编辑  收藏  举报