我分到的是模4余0和余1的题目
int main()
{
cout<<"Hello World!"<
int main()
{
int f; scanf("%d", &f);
printf("Celsius = %d\n", 5*(f-32)/9);
return 0;
}
每个PAT考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。
输入格式:
输入第一行给出一个正整数N(<=1000),随后N行,每行给出一个考生的信息:“准考证号 试机座位号 考试座位号”。其中准考证号由14位数字组成,座位从1到N编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。
考生信息之后,给出一个正整数M(<=N),随后一行中给出M个待查询的试机座位号码,以空格分隔。
输出格式:
对应每个需要查询的试机座位号码,在一行中输出对应考生的准考证号和考试座位号码,中间用1个空格分隔。
输入样例:4 10120150912233 2 4 10120150912119 4 1 10120150912126 1 3 10120150912002 3 2 2 3 4输出样例:
10120150912002 2 10120150912119 1
建立第二个数和第一个数的映射以及第二个数和第三个数的映射
const int maxn = 1010;
int mmap1[maxn];
string mmap2[maxn];
int main()
{
int n; scanf("%d", &n);
rep(i, n){
string s; int x, y;
cin>>s;scanf("%d%d", &x, &y);
mmap1[x] = y; mmap2[x] = s;
}
int m; scanf("%d", &m);
rep(i, m){
int x; scanf("%d", &x);
printf("%s %d\n", mmap2[x].c_str(), mmap1[x]);
}
return 0;
}
给定两个整数A和B,输出从A到B的所有整数以及这些数的和。
输入格式:
输入在一行中给出2个整数A和B,其中-100<=A<=B<=100,其间以空格分隔。
输出格式:
首先顺序输出从A到B的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐。最后在一行中输出全部数字的和。
输入样例:-3 8输出样例:
-3 -2 -1 0 1 2 3 4 5 6 7 8 Sum = 30
int main()
{
int l,r; scanf("%d%d", &l, &r);
For(i, l, r){
printf("%5d", i);
if ((i-l) % 5 == 4) pn;
}
if ((r-l) % 5 != 4) pn;
printf("Sum = %d\n", (l+r) * (r-l+1) / 2);
return 0;
}
本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数“分子/分母”的形式给出的,你输出的和也必须是有理数的形式。
输入格式:
输入第一行给出一个正整数N(<=100)。随后一行按格式“a1/b1 a2/b2 ...”给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。
输出格式:
输出上述数字和的最简形式 —— 即将结果写成“整数部分 分数部分”,其中分数部分写成“分子/分母”,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
输入样例1:5 2/5 4/15 1/30 -2/60 8/3输出样例1:
3 1/3输入样例2:
2 4/3 2/3输出样例2:
2输入样例3:
3 1/3 -1/6 1/8输出样例3:
7/24
struct frac{
int up, down;
frac(int _up = 0, int _down = 0) : up(_up), down(_down){}
frac operator + (const frac& b){
frac tmp;
tmp.down = down * b.down;
tmp.up = up * b.down + down * b.up;
int gcd1 = gcd(abs(tmp.up), abs(tmp.down));
tmp.down /= gcd1; tmp.up /= gcd1;
return tmp;
}
};
然后读入进行模拟,这题的输出要分5种情况
1、答案是0
2、分母是1
3、真分数
4、正假分数
5、负假分数
对于第五种情况,题面没有说清楚应该怎么输出,比如-11/3是输出-4+1/3还是-3-2/3呢?
这个经过探索,应该用第二种处理方式
int gcd(int a, int b){
return a % b == 0 ? b : gcd(b, a % b);
}
struct frac{
int up, down;
frac(int _up = 0, int _down = 0) : up(_up), down(_down){}
frac operator + (const frac& b){
frac tmp;
tmp.down = down * b.down;
tmp.up = up * b.down + down * b.up;
int gcd1 = gcd(abs(tmp.up), abs(tmp.down));
tmp.down /= gcd1; tmp.up /= gcd1;
return tmp;
}
};
frac a[1000];
int main(){
int n; scanf("%d", &n);
rep(i, n) scanf("%d/%d", &a[i].up, &a[i].down);
frac ans; ans = frac(0,1);
rep(i, n) ans = ans + a[i];
if (ans.up == 0) printf("0");
else if (ans.down == 1) printf("%d", ans.up);
else if (abs(ans.up) < ans.down) printf("%d/%d", ans.up, ans.down);
else if (ans.up > 0){
int z1 = ans.up / ans.down;
ans.up %= ans.down;
printf("%d %d/%d", z1, ans.up, ans.down);
}else{
ans.up = -ans.up;
int z1 = ans.up / ans.down;
ans.up %= ans.down;
printf("-%d %d/%d", z1, ans.up, ans.down);
}
return 0;
}
真的没骗你,这道才是简单题 —— 对任意给定的不超过10的正整数n,要求你输出2n。不难吧?
输入格式:
输入在一行中给出一个不超过10的正整数n。
输出格式:
在一行中按照格式“2^n = 计算结果”输出2n的值。
输入样例:5输出样例:
2^5 = 32
记得用位运算。
int main()
{
int n;scanf("%d", &n);
printf("%d^%d = %d", 2, n, 1<
int main()
{
int n; scanf("%d", &n);
int sum = 0, mul = 1;
rep1(i, n){
mul *= i;
sum += mul;
}
printf("%d\n", sum);
return 0;
}
一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:
首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后将计算的和对11取模得到值Z;最后按照以下关系对应Z值与校验码M的值:
Z:0 1 2 3 4 5 6 7 8 9 10
M:1 0 X 9 8 7 6 5 4 3 2
现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。
输入格式:
输入第一行给出正整数N(<= 100)是输入的身份证号码的个数。随后N行,每行给出1个18位身份证号码。
输出格式:
按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理,只检查前17位是否全为数字且最后1位校验码计算准确。如果所有号码都正常,则输出“All passed”。
输入样例1:4 320124198808240056 12010X198901011234 110108196711301866 37070419881216001X输出样例1:
12010X198901011234 110108196711301866 37070419881216001X输入样例2:
2 320124198808240056 110108196711301862输出样例2:
All passed
顺带一提,第一个权重分配其实不用都抄,是有规律的
char s[100];
int map1[] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
char map2[] = "10X98765432";
int main()
{
int n; scanf("%d", &n);
int flag = 1;
rep(i, n){
scanf("%s", s);
int sum = 0;
rep(i, 17) sum += map1[i] * (s[i] - '0');
sum %= 11;
if (s[17] != map2[sum]){
flag = 0;
printf("%s\n", s);
}
}
if (flag) printf("All passed\n");
return 0;
}
一个整数“犯二的程度”定义为该数字中包含2的个数与其位数的比值。如果这个数是负数,则程度增加0.5倍;如果还是个偶数,则再增加1倍。例如数字“-13142223336”是个11位数,其中有3个2,并且是负数,也是偶数,则它的犯二程度计算为:3/11*1.5*2*100%,约为81.82%。本题就请你计算一个给定整数到底有多二。
输入格式:
输入第一行给出一个不超过50位的整数N。
输出格式:
在一行中输出N犯二的程度,保留小数点后两位。
输入样例:-13142223336输出样例:
81.82%
模拟题
char s[100];
int main()
{
scanf("%s", s);
int len = s[0] == '-' ? strlen(s) - 1 : strlen(s);
double base = 1;
if (s[0] == '-') base *= 1.5;
if ( (s[strlen(s)-1] - '0') % 2 == 0) base *= 2;
int cnt = 0;
rep(i, strlen(s)) if ( (s[i] - '0') == 2) ++cnt;
base = base * cnt / len;
printf("%.2f%\n", base * 100);
return 0;
}
当芸芸众生忙着在朋友圈中发照片的时候,总有一些人因为太帅而没有朋友。本题就要求你找出那些帅到没有朋友的人。
输入格式:
输入第一行给出一个正整数N(<=100),是已知朋友圈的个数;随后N行,每行首先给出一个正整数K(<=1000),为朋友圈中的人数,然后列出一个朋友圈内的所有人——为方便起见,每人对应一个ID号,为5位数字(从00000到99999),ID间以空格分隔;之后给出一个正整数M(<=10000),为待查询的人数;随后一行中列出M个待查询的ID,以空格分隔。
注意:没有朋友的人可以是根本没安装“朋友圈”,也可以是只有自己一个人在朋友圈的人。虽然有个别自恋狂会自己把自己反复加进朋友圈,但题目保证所有K超过1的朋友圈里都至少有2个不同的人。
输出格式:
按输入的顺序输出那些帅到没朋友的人。ID间用1个空格分隔,行的首尾不得有多余空格。如果没有人太帅,则输出“No one is handsome”。
注意:同一个人可以被查询多次,但只输出一次。
输入样例1:3 3 11111 22222 55555 2 33333 44444 4 55555 66666 99999 77777 8 55555 44444 10000 88888 22222 11111 23333 88888输出样例1:
10000 88888 23333输入样例2:
3 3 11111 22222 55555 2 33333 44444 4 55555 66666 99999 77777 4 55555 44444 22222 11111输出样例2:
No one is handsome
一是注意注意%05d的运用
二是每个人至多被查询一次
三是怎么输出,因为行末要求没有空格的,我的做法就是输出第一个答案的时候不输出空格,其他数先输出一个空格
int vis[100010];
int main()
{
int n; scanf("%d", &n);
rep(i, n){
int k,x; scanf("%d", &k);
rep(i, k){
scanf("%d", &x);
if (k != 1)vis[x] = 1;
}
}
int m; scanf("%d", &m);
int flag = 0;
rep(i, m) {
int x; scanf("%d", &x);
if (vis[x] == 0){
vis[x] = 1;
if (flag) printf(" ");
printf("%05d", x);
flag = 1;
}
}
if (flag == 0) printf("No one is handsome\n");
return 0;
}
int main()
{
rep(i, 3) printf("I'm gonna WIN!\n");
return 0;
}
int main()
{
int x; scanf("%d", &x);
printf("%d\n", (x+1) % 7 + 1);
return 0;
}
作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。
输入格式:
输入第一行给出4个正整数N、M、S、D,其中N(2<=N<=500)是城市的个数,顺便假设城市的编号为0~(N-1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。
输出格式:
第一行输出不同的最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出首尾不能有多余空格。
输入样例:4 5 0 3 20 30 40 10 0 1 1 1 3 2 0 3 3 0 2 2 2 3 2输出样例:
2 60 0 1 3
首先要去一个靠谱的网站学习最短路,我推荐VisuAlgo
用一种最短路算法得到结果,比如叫dis数组,dis[u]表示从起点到u的最短路
这样就有一棵隐式的最短路径树出来了,d[v] = d[u] + dis(u,v)成立则(u,v)有边,容易知道这是一个有向无环图
对于最短路条数的计数,在这个树上进行dp,dp[u] = sum(dp[v]) (u,v在最短路径树上有边) 注意起点的dp值为0
救援队最多也是类似的做法,设val[u]为u点的救援队数量,dp[u] = max(dp[v]) + val[u]); (u,v在最短路径树上有边) dp的同时记录下那个v,这样就能输出路径了。
我们觉得最短路的条数可能是阶乘级的,但斗胆没有写大整数,阶乘级的答案时间都是个问题
const int maxn = 550;
typedef pair pii;
struct edge{
int v, w;
edge(int _v = 0, int _w = 0) : v(_v), w(_w){}
};
vector g[maxn];
int dis[maxn], v[maxn], d2[maxn], n, m, st, ed, prv[maxn];
ll d[maxn];
vector ans;
void add1(int u, int v, int w){
g[u].push_back(edge(v, w));
g[v].push_back(edge(u, w));
}
void dijkstra(int s){
priority_queue, greater > q;
rep(i, n) dis[i] = inf;
dis[s] = 0;
q.push(make_pair(dis[s], s));
while(!q.empty()){
pii tmp = q.top(); q.pop();
int u = tmp.second;
if (dis[u] != tmp.first) continue;
rep(i, g[u].size()){
edge e = g[u][i];
if (dis[e.v] > dis[u] + e.w){
dis[e.v] = dis[u] + e.w;
q.push(make_pair(dis[e.v], e.v));
}
}
}
}
//计算最短路径的条数
ll dp(int u){
if (d[u] != -1) return d[u];
ll &ans = d[u];
ans = 0;
if (u == st) ans = 1;
else
rep(i, g[u].size()){
edge e = g[u][i];
if (dis[u] == dis[e.v] + e.w) ans += dp(e.v);
}
return ans;
}
//计算点权和的最大值
int dp2(int u){
if (d2[u] != -1) return d2[u];
int &ans = d2[u];
ans = v[u];
int tmp = st;
rep(i, g[u].size()){
edge e = g[u][i];
if (dis[u] == dis[e.v] + e.w && dp2(tmp) < dp2(e.v))
tmp = e.v;
}
if (u == st) prv[u] = -1;
else { prv[u] = tmp; ans += dp2(tmp); }
return ans;
}
int main()
{
scanf("%d%d%d%d", &n, &m, &st, &ed);
rep(i, n) scanf("%d", v + i);
rep(i, m){
int u, v, w; scanf("%d%d%d", &u, &v, &w);
add1(u, v, w);
}
dijkstra(st);
memset(d, -1, sizeof(d));
memset(d2, -1, sizeof(d2));
printf("%lld %d\n", dp(ed), dp2(ed));
int now = ed;
while(now != -1){
ans.push_back(now);
now = prv[now];
}
printf("%d", ans[ans.size()-1]);
for(int i = ans.size()-2; i >= 0; i--)printf(" %d", ans[i]); pn;
return 0;
}
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数N(<=1000)。随后一行给出N个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出“YES”,然后在下一行输出该树后序遍历的结果。数字间有1个空格,一行的首尾不得有多余空格。若答案是否,则输出“NO”。
输入样例1:7 8 6 5 7 10 8 11输出样例1:
YES 5 7 6 8 11 10 8输入样例2:
7 8 10 11 8 6 7 5输出样例2:
YES 11 8 10 7 5 6 8输入样例3:
7 8 6 8 5 10 9 11输出样例3:
NO
假设左子树更小右子树更大的情况,另一种情况可以类似地考虑。
以样例为例来说明。
先看样例1,8显然是树根,8后面的6个数是8的左子树或右子树,而左子树里的元素比8小,右子树里的元素大于等于8
可以得出6 5 7这三个元素是左子树里的,另三个是右子树里的。
再看6 5 7,显然6是这个子树的根,5是6的左儿子,7是6的右儿子。
按照这个思路进行递归处理就能完成判断和建树,然后做后序遍历即可。
对于样例3,8的左子树只能到6,但后面5个元素里有比8小的,因此无法构造,按相反顺序做一遍也不行,因此不行。
const int maxn = 1010;
int a[maxn], n;
vector ans;
bool cmp(int x, int y, int t){
if (t == 0) return x >= y;
else return x < y;
}
//判断a[l,r]是否合法,x=0代表递增的情况,x=1代表递减的情况
bool judge(int l, int r, int x){
if (l >= r) return true;
int key = a[l], k;
for(k = l + 1; k <= r; k++)
if (cmp(a[k], key, x)) break;
for(int i = k+1; i <= r; i++)
if (!cmp(a[i], key, x)) return false;
return judge(l+1, k-1, x) && judge(k, r, x);
}
struct node{
int val;
node* ch[2];
};
node* build(int l, int r, int x){
if (l > r) return NULL;
node* tmp = new node;
int key = a[l], k;
tmp->val = key; tmp->ch[0] = tmp->ch[1] = NULL;
if (l == r) return tmp;
for(k = l + 1; k <= r; k++)
if (cmp(a[k], key, x)) break;
tmp->ch[0] = build(l+1, k-1, x);
tmp->ch[1] = build(k, r, x);
return tmp;
}
void dfs(node *x){
rep(i, 2) if (x->ch[i] != NULL) dfs(x->ch[i]);
ans.push_back(x->val);
}
int main()
{
int flag[2]; node *root;
scanf("%d", &n);
rep1(i, n) scanf("%d", &a[i]);
rep(i, 2) flag[i] = judge(1, n, i);
if (flag[0] || flag[1]){
printf("YES\n");
rep(i, 2) if (flag[i]) root = build(1, n, i);
dfs(root);
printf("%d", ans[0]);
rep1(i, ans.size()-1) printf(" %d", ans[i]);
}else printf("NO\n");
return 0;
}
给定两个整数集合,它们的相似度定义为:Nc/Nt*100%。其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。
输入格式:
输入第一行给出一个正整数N(<=50),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(<=104),是集合中元素的个数;然后跟M个[0, 109]区间内的整数。
之后一行给出一个正整数K(<=2000),随后K行,每行对应一对需要计算相似度的集合的编号(集合从1到N编号)。数字间以空格分隔。
输出格式:
对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后2位的百分比数字。
输入样例:3 3 99 87 101 4 87 101 5 87 7 99 101 18 5 135 18 99 2 1 2 1 3输出样例:
50.00% 33.33%