某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过200岁的老人,而今天是2014年9月6日,所以超过200
岁的生日和未出生的生日都是不合理的,应该被过滤掉。
输入在第一行给出正整数N,取值在(0, 105];随后N行,每行给出1个人的姓名(由不超过5个英文字母组成的字符串)、以及
按“yyyy/mm/dd”(即年/月/日)格式给出的生日。题目保证最年长和最年轻的人没有并列。
在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。
5<br/>John 2001/05/12<br/>Tom 1814/09/06<br/>Ann 2121/01/30<br/>James 1814/09/05<br/>Steve 1967/11/20
3 Tom John
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* 人口普查
* 题目描述
* 某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
* 这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过200岁的老人,
* 而今天是2014年9月6日,所以超过200岁的生日和未出生的生日都是不合理的,应该被过滤掉。
* 输入描述:
* 输入在第一行给出正整数N,取值在(0, 105];随后N行,每行给出1个人的姓名(由不超过5个
* 英文字母组成的字符串)、以及按“yyyy/mm/dd”(即年/月/日)格式给出的生日。题目保证最
* 年长和最年轻的人没有并列。
* 输出描述:
* 在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。
* 输入例子:
* 5
* John 2001/05/12
* Tom 1814/09/06
* Ann 2121/01/30
* James 1814/09/05
* Steve 1967/11/20
* 输出例子:
* 3 Tom John
*
* @author shijiacheng
* @date 2018/2/1
*/
public class B1018Census {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
List<Person> list = new ArrayList<>();
for (int i = 0; i < N; i++) {
Person p = new Person();
p.name = sc.next();
p.setDateStr(sc.next());
list.add(p);
}
int count = 0;
int min = 0;
int max = Integer.MAX_VALUE;
String maxName = "";
String minName = "";
for (int i = 0; i < list.size(); i++) {
if (list.get(i).date >= 18140906 && list.get(i).date <= 20140906) {
count++;
if (list.get(i).date < max) {
max = list.get(i).date;
maxName = list.get(i).name;
}
if (list.get(i).date > min) {
min = list.get(i).date;
minName = list.get(i).name;
}
}
}
System.out.println(count + " " + maxName + " " + minName);
}
static class Person {
String name;
int date;
String dateStr;
public void setDateStr(String dateStr) {
this.dateStr = dateStr;
String[] str = dateStr.split("/");
this.date = Integer.parseInt(str[0]) * 10000
+ Integer.parseInt(str[1]) * 100 + Integer.parseInt(str[2]);
}
}
}
import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class Main { public static class Person implements Comparable<Person> { String name; String birthday; public Person(String name, String birthday) { this.name = name; this.birthday = birthday; } public int compareTo(Person o){ return this.birthday.compareTo(o.birthday); } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); ArrayList<Person> person = new ArrayList<>(); for (int i = 0; i < n; i++) { Person p = new Person(in.next(), in.next()); person.add(p); } Collections.sort(person); Person p1 = new Person("tom","2014/09/06"); Person p2 = new Person("tom","1814/09/06"); int count = 0; boolean flag1 = true; String[] name = new String[2]; for (Person p : person) { if (p.compareTo(p2) >= 0 && p.compareTo(p1) <= 0) { count++; } if (p.compareTo(p2) >= 0 && flag1) { name[0] = p.name; flag1 = false; } if (p.compareTo(p1) <= 0) { name[1] = p.name; } } System.out.printf("%d %s %s", count, name[0], name[1]); } }
void test03() { /* "1814/09/06" ~ "2014/09/06" 的才正确 */ int nums, flag = 1, count = 0; map<string, string> person; string name, birth, youngest, oldest; cin >> nums; while(nums--){ cin >> name >> birth; if(birth>="1814/09/06" && birth<="2014/09/06") count++; person.insert(make_pair(birth, name)); } map<string, string>::iterator map_it = person.begin(); while(map_it!=person.end()){ if( map_it->first<"1814/09/06" || map_it->first>"2014/09/06" ){ map_it++; continue; } if(flag){ oldest = map_it->second; flag = 0; } youngest = map_it->second; map_it++; } cout << count << " " << oldest << " " << youngest; } int main() { test03(); return 0; }
#include<stdio.h> #include<string.h> int main (){//the shorter,the better. int n,i,cnt;char b[11],max[11]="1814/09/06",min[11]="2014/09/06",t[6],o[6],y[6]; for(;~scanf("%d",&n);printf("%d %s %s\n",cnt,y,o)) for (cnt=i=0; i < n&&~scanf("%s %s",t,b);strcmp(b,"1814/09/06")<0||strcmp(b,"2014/09/06")>0?:(strcmp(max,b)>0?:(strcpy(max,b),strcpy(o,t),1),strcmp(min,b)<0?:(strcpy(min,b),strcpy(y,t),1),++cnt),i++); }//ps:ANSI C has lots of handsome functions,why not just use then?-_-
#include<iostream> #include<algorithm> using namespace std; const int maxn = 100010; struct Per{ char name[5]; int year, month, day; int rank; }per[maxn]; bool judge(Per a){ if (a.year>2014 || a.year<1814) return false; else if (a.year == 2014 && a.month>9 || a.year == 1814 && a.month<9) return false; else if (a.year == 2014 && a.month == 9 && a.day>6 || a.year == 1814 && a.month == 9 && a.day<6) return false; else return true; } bool cmp(Per a, Per b){ if (a.rank != b.rank)return a.rank > b.rank; if (a.year != b.year) return a.year>b.year; else if (a.month != b.month) return a.month>b.month; else return a.day>b.day; } int main(){ int n; cin >> n; int cnt = 0; for (int i = 0; i<n; i++){ cin >> per[i].name; scanf_s("%d/%d/%d", &per[i].year, &per[i].month, &per[i].day); if (judge(per[i])){ cnt++; per[i].rank = 1; } else per[i].rank = 0; } cout << cnt << " "; sort(per, per + n, cmp); cout << per[cnt - 1].name<<" " << per[0].name; }
年月日比较法,按顺序依次比较年月日,封装成函数。
利用字符串的顺序比较,借助STL
的string
直接比较得出结果,不需要封装函数。
注意:结果为0时,只需要输出0,而不需要其他,包括空格。
年月日依次比较
/* * app=PAT-Basic lang=c++ * https://pintia.cn/problem-sets/994805260223102976/problems/994805293282607104 */ #include <cstdio> #include <cstring> using namespace std; const int maxn = 100010; struct person{ char name[6]; int year; int month; int day; }temP,maxP,minP,max,min; /* * 年份,月份,天均小于等于 --- 年龄大于等于 */ bool lessEqu(person p1,person p2){ if (p1.year != p2.year) return p1.year <= p2.year; if (p1.month != p2.month) return p1.month <= p2.month; else return p1.day <= p2.day; } /* * 年份,月份,天均大于等于 --- 年龄小于等于 */ bool moreEqu(person p1, person p2){ if (p1.year != p2.year) return p1.year >= p2.year; if (p1.month != p2.month) return p1.month >= p2.month; else return p1.day >= p2.day; } void init(){ minP.year = min.year = 1814; maxP.year = max.year = 2014; maxP.month = minP.month = max.month = min.month = 9; maxP.day = minP.day = max.day = min.day = 6; } int main() { int n; int year, month, day; init(); scanf("%d",&n); int count = 0; for (int i = 0; i < n; i++){ scanf("%s %d/%d/%d", temP.name, &temP.year, &temP.month, &temP.day); if (lessEqu(temP, max) && moreEqu(temP, min)){ count++; if (lessEqu(temP, maxP)){ maxP = temP; } if (moreEqu(temP, minP)){ minP = temP; } } } printf("%d",count); if (count!=0) printf(" %s %s", maxP.name, minP.name); return 0; }
直接利用
STL:string
比较。不需要自封装比较函数,但是不熟悉string
方法的,需要知道string
的比较判断,是按照字符顺序的ascii
码比较,所以可以用string的直接比较来解决。
/* * app=PAT-Basic lang=c++ * https://pintia.cn/problem-sets/994805260223102976/problems/994805293282607104 */ #include <cstdio> #include <string> #include <iostream> using namespace std; int main(){ int n; scanf("%d",&n); int count = 0; string s1, s2, left = "1814/09/06", right = "2014/09/06"; string max = right, min = left, maxName, minName; for (int i = 0; i < n; i++){ cin >> s1 >> s2; if (s2 >= left && s2 <= right){ count++; if (s2 < max){ max = s2; maxName = s1; } if (s2 >min){ min = s2; minName = s1; } } } cout << count; if (count != 0) cout << " " << maxName << " " << minName << endl; return 0; }
PAT、牛客网通过代码
#include<iostream> using namespace std; int main(){ int N; int birth; string date; string name; int max=18140906,min=20140906; int maxIndex,minIndex; string maxName,minName; cin>>N; int qualifiedNum=N; if(N>0){//没有这步判断 测试点3段错误 for(int i=0;i<N;i++){ cin>>name>>date; birth=stoi(date.substr(0,4))*10000+stoi(date.substr(5,2))*100+stoi(date.substr(8,2)); //谁的出生日期的整数值,小的最小,大的最大 if(birth>20140906||birth<18140906){//不在合法范围 //birth=0;//不合法生日置零 qualifiedNum--;//合法数字-- }else{//在合法范围 if(max<birth){//最大值 max=birth; maxIndex=i; maxName=name; } if(min>birth){//最小值 min=birth; minIndex=i; minName=name; } } } if(qualifiedNum==0){//如果所有数据都不合法 输出0,否则测试点3格式错误 cout<<"0"; return 0; } cout<<qualifiedNum<<" "<<minName<<" "<<maxName; } return 0; }
#include <iostream> #include <string> //#include<string.h> #include<list> using namespace std; string String2int(string it) { string sub; int i = it.find(" ", 0); sub = it.substr(i + 1, it.size() - i - 1); int j = sub.find_first_of("/", 0); sub.erase(j, 1); int z = sub.find("/", 0); sub.erase(z, 1); return sub; } int main() { int N; cin >> N; cin.get(); list<string> str; while (N>0) { string tmp; getline(cin, tmp); str.push_back(tmp); N--; } for (list<string>::iterator it = str.begin();it != str.end();) { string sub = String2int(*it); if (stoi(sub)>20140906||stoi(sub)<18140906) { str.erase(it++); } else { it++; } } cout << str.size(); string max, min; //max = min = "20140906"; bool flag = false; for (list<string>::iterator it = str.begin();it != str.end();it++) { string sub = String2int(*it); if (!flag) { min = max = sub; flag = true; } else { //max = min = sub; if (stoi(max)>stoi(sub)) { max = sub; } else if (stoi(min)<stoi(sub)) { min = sub; } } } //bool tag = false; for (list<string>::iterator it = str.begin();it != str.end();it++) { string sub = String2int(*it); int i = it->find(" ", 0); if (stoi(max)==stoi(sub)) { cout <<" "<< it->substr(0, i); } } for (list<string>::iterator it = str.begin();it != str.end();it++) { string sub = String2int(*it); int i = it->find(" ", 0); if (stoi(min) == stoi(sub)) { cout << " " << it->substr(0, i); } } cout << endl; system("pause"); return 0; }比较通俗易懂的代码,不过代码量有点大,思路简单直白
#在输入的过程中进行查找,不用保存下来。节省空间 try: while True: num = int(input()) pastDays = '1814/09/06' #初始化最早的出生日期 nowDays = '2014/09/06' #最晚的生日 young = '1814/09/06' #初始化年轻人的生日为最老 elder = '2014/09/06' #初始化老年人的生日为最年轻 legal = 0 for i in range(num): #输入中比较 temp = input().split() if pastDays <= temp[1] <= nowDays: legal += 1 if temp[1] > young: youngName = temp[0] young = temp[1] if temp[1] < elder: elder = temp[1] elderName = temp[0] print("%d %s %s" % (legal,elderName,youngName)) except Exception: pass
#include <iostream> #include<string> #include<vector> #include<algorithm> using namespace std; typedef struct node { string name; string date; int age; bool test() { bool sta; int sum = 0, t; for (auto c : date) { if (c >= '0'&&c <= '9') sum = sum * 10 + c - '0'; } age = sum; if (20140906 - sum <= 2000000 && sum < 20140906) sta = true; else sta = false; return sta; } }node; bool cmp(const node& x, const node& y) { return x.age < y.age; } int main() { int length; while (cin >> length) { node n; vector<node> data; for (int i = 0; i < length; i++) { cin >> n.name >> n.date; if (n.test() == true) data.push_back(n); } sort(data.begin(), data.end(), cmp); cout << data.size() << " " << data[0].name << " " << data[data.size() - 1].name << endl; } return 0; }
#include<iostream>#include<string.h>using namespace std;// PAT乙级人口普查(20)bool timeCompare(chartime1[11],chartime2[11]);intmain(){intN,i,cnt=0;cin>>N;charnames[10],OldName[10],YoungName[10];chartimes[11],OldTime[11]="1814/09/05",YoungTime[11]="2015/09/07";charStartTime[11]="1814/09/05",FinishTime[11]="2015/09/07";for(i=0;i<N;i++){cin>>names>>times;if((timeCompare(times,StartTime)) &&(timeCompare(FinishTime,times))){cnt++;//find the oldest oneif(timeCompare(YoungTime,times)){strcpy(YoungTime,times);strcpy(OldName,names);}//find the youngest oneif(timeCompare(times,OldTime)){strcpy(OldTime,times);strcpy(YoungName,names);}}}if(cnt>0)cout<<cnt<<" "<<OldName<<" "<<YoungName<<endl;elsecout<<"0";return0;}//compare the timesbool timeCompare(chartime1[11],chartime2[11]){//time1 > time2 return true;inti;for(i=0;i<10;i++){if(time1[i] - time2[i] > 0)returntrue;if(time1[i] - time2[i] < 0)returnfalse;}returnfalse;}
import java.util.Scanner; public class Main { private static final int TODAY = 20140906; private static final int LIMIT = 18140906; public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; String eldest = null; String youngest = null; int count = 0; while(--n>=0){ String name = in.next(); String date = in.next(); String[] d = date.split("/"); int time = Integer.parseInt(d[0]); time = time*100+(d[1].charAt(0)-'0')*10+(d[1].charAt(1)-'0'); time = time*100+(d[2].charAt(0)-'0')*10+(d[2].charAt(1)-'0'); if(time>TODAY) continue; if(time<LIMIT) continue; count++; if(time>max){ max = time; youngest = name; } if(time<min){ min = time; eldest = name; } } System.out.println(count+" "+eldest+" "+youngest); } }
#include<iostream> #include<string> #include<algorithm> using namespace std; struct people { string name; int y, m, d; bool operator <(const people& l)const { if (y<l.y) return true; if (y == l.y) { if (m<l.m) return true; if (m == l.m) return d<l.d; return false; } return false; } }; people a[100005]; int main() { int n, i = 0, y, m, d; string name, tmp, tmp1, tmp2, tmp3; cin >> n; while (n--) { cin >> name >> tmp; tmp1 = tmp.substr(0, 4); tmp2 = tmp.substr(5, 2); tmp3 = tmp.substr(8, 2); y = (tmp1[0] - '0') * 1000 + (tmp1[1] - '0') * 100 + (tmp1[2] - '0') * 10 + tmp1[3] - '0'; m = (tmp2[0] - '0') * 10 + tmp2[1] - '0'; d = (tmp3[0] - '0') * 10 + tmp3[1] - '0'; if (y > 2014 || y < 1814) continue; else if (y == 2014 || y == 1814) { if (y == 2014) { if (m > 9) continue; else if (m == 9) { if (d > 6) continue; } } else { if (m < 9) continue; else if (m == 9) { if (d < 6) continue; } } } a[i].y = y; a[i].m = m; a[i].d = d; a[i].name = name; i++; } sort(a, a + i); cout << i << " " << a[0].name << " " << a[i - 1].name; return 0; }
#include<iostream> #include<cmath> #include<cstdio> #include<cstring> using namespace std; int main() { int n,cnt=0,max_i=-1,min_i=-1; cin>>n; string name[100000],birthday[100000]; string oldday="2014/09/06",youngday="1814/09/06"; //和总是把max初始化为最小道理一样 for(int i=0;i<n;i++) { cin>>name[i]>>birthday[i]; if(birthday[i]>="1814/09/06" && birthday[i]<="2014/09/06") { cnt++; if(birthday[i]>=youngday)//在合法的情况下查找最大和最小 { youngday=birthday[i]; min_i=i; } if(birthday[i]<=oldday) { oldday=birthday[i]; max_i=i; } } } if(cnt>0) { cout<<cnt<<" "; cout<<name[max_i]<<" "<<name[min_i]; } else cout<<"0"; return 0; }
#include <iostream> using namespace std; int main() { ios::sync_with_stdio(false); int N; cin >> N; string name, str; string minStr="z", minName=""; string maxStr="", maxName=""; string start = "1814/09/06"; string end = "2014/09/06"; int counts = 0; for(int i=0; i<N; i++) { cin >> name >> str; if(str>=start && str<=end) { counts++; if(minStr > str) { minStr = str; minName = name; } if(maxStr < str) { maxStr = str; maxName = name; } } } cout << counts << " " << minName << " " << maxName << endl; return 0; }
#include <iostream>