赞
踩
早晨,去批发市场买牛奶。第i个牛奶卖主允许以所需价格购买任意数量的牛奶,每瓶牛奶的价格为si。(每个卖主的牛奶都一样)
傍晚,有m个出售牛奶的地方。第i个地方允许以bi的价格出售任意数量的牛奶。您所卖出的牛奶数量不能超过自己已有的牛奶数量。
现在是早晨,您拥有r元而没有牛奶。晚上之后您可以拥有最多多少钱?
输入共三行。
第一行包含三个整数n,m,r(1≤n≤30,1≤m≤30,1≤r≤1000),分别表示市场上牛奶卖主数目、出售牛奶的地方数以及您现在拥有的钱数;
第二行有n个整数s1,s2,…,sn(1≤si≤1000),si表示有机会以si的价格购买牛奶;
第三行有m个整数b1,b2,…,bm(1≤bi≤1000),bi表示有机会以bi的价格出售牛奶。
晚上之后,卖主最多可以拥有的钱数。
1 2 10
3
2 4
13
最小值买入,最大值卖出,简单的排序就能搞定。
#include<bits/stdc++.h> using namespace std; int main() { int n, m, r; int s[1001], b[1001]; cin >> n >> m >> r; int i, j; for (i = 0; i < n; i++) cin >> s[i]; for (i = 0; i < m; i++) cin >> b[i]; int num, money = 0; sort(s, s + n); sort(b, b + m); num = r / s[0]; money = r % s[0]; money += b[m - 1] * num; if (money >= r) cout << money; else cout << r; return 0; }
航船游戏中,风向每个单位时间会改变一次,每次航船可以选择顺风前行一个单位距离,也可以选择原地不动。游戏时长为 t,请你计算从起点出发,最终到达终点所需要的最少移动次数。如果游戏结束也到达不了终点,则输出-1。
第一行包括一个正整数 t(1<=t<=100000)。
第二行为起点坐标(x1 , y1)。
第三行为终点坐标(x2 , y2)。
接下来 t 行,每行输入一个单词,表示风向 。
输出为一个整数,为到达终点所需移动的最少步数;如果无法到达,输出-1。
5
1 1
2 2
east
north
west
west
north
2
累加四个方向的步数,算出起点与终点之间横向与纵向的距离,判断此方向的步数是否大于距离。
#include<bits/stdc++.h> using namespace std; int main() { int t, x1, x2, y1, y2; int ans, step = 0; int e = 0, n = 0, w = 0, s = 0; int i; char a[10]; cin>>t; cin>>x1>>y1; cin>>x2>>y2; ans=abs(x1-x2)+abs(y1-y2); for (i = 0; i < t; i++) { memset(a,'\0',sizeof(a)); scanf("%s",a); if (a[0] == 'e') e++; if (a[0] == 'w') w++; if (a[0] == 'n') n++; if (a[0] == 's') s++; } if (x2-x1 >= 0 && e >= abs(x1-x2)) step++; if (x2-x1 < 0 && w >= abs(x1-x2)) step++; if (y2-y1 >= 0 && n >= abs(y1-y2)) step++; if (y2-y1 < 0 && s >= abs(y1-y2)) step++; if (step == 2) printf("%d",ans); else printf("-1"); return 0; }
相信大家都学过一元n次多项式的书写规则,现在给出多项式的系数,请让你帮忙写出这个多项式。
输入共有两 行。 第一行 1 个整数n,表示一元多项式的次数(0<=n<=100)。 第二行有 n+1 个整数,其中第 i 个整数表示第 n-i+1 次项的系数,每两个整数之间用空格隔开(-100<=系数<=100)。
输出共 1 行,按题目所述格式输出多项式。
5
10 -1 1 -3 0 10
10x5-x4+x3-3x2+10
3
-5 0 0 1
5x3+1
#include<bits/stdc++.h> using namespace std; int main() { int n; int a[200]; cin >> n; int i; for (i = 0; i <= n; i++) { cin >> a[i]; } if (n < 2) { if (n == 1) { if (a[0] != 0) { if (a[0] != -1 && a[0] != 1) cout << a[0] << "x"; if (a[0] == 1) cout << "x"; if (a[0] == -1) cout << "-x"; } if (a[1] > 0) cout << "+" << a[1]; if (a[1] < 0) cout << a[1]; } if (n == 0) { cout << a[0]; } } else { if (a[0] != 0) { if (a[0] != -1 && a[0] != 1) cout << a[0] << "x^" << n; if (a[0] == 1) cout << "x^" << n; if (a[0] == -1) cout << "-x^" << n; } for (i = 1; i < n - 1; i++) { if (a[i] > 0) { if (a[i] != 1) cout << "+" << a[i] << "x^" << n - i; else cout << "+" << "x^" << n - i; } if (a[i] < 0) { if (a[i] != -1) cout << a[i] << "x^" << n - i; else cout << "-" << "x^" << n - i; } } if (a[n - 1] > 0) { if (a[n - 1] != 1) cout << "+" << a[n - 1] << "x"; else cout << "+x"; } if (a[n - 1] < 0) { if (a[n - 1] != -1) cout << a[i] << "x"; else cout << "-x"; } if (a[n] > 0) cout << "+" << a[n]; if (a[n] < 0) cout << a[n]; } return 0; }
设有n个任务,其中每个任务有一个起始时间si和一个结束时间ei,且si<ei,同一时间只能完成一个任务。如果选择了任务i ,则它在时间区间 [si ,ei) 内占用资源。若区间 [si ,ei) 与区间 [sj, ej)不相交,则称任务 i 与任务 j 是相容的。那么,对于给定的任务时间区间,能互相兼容的最大任务个数是多少呢?
第一行一个整数n (1<=n<=1000) ;
接下来n行,每行两个整数si 和 ei。
互相兼容的最大任务个数。
4
1 3
4 6
2 5
1 7
2
结构体中存储开始与结束时间,按照结束时间排序,第一个即为任务1,接着循环找出开始时间在此之后的任务2,以此类推,累加任务数。
#include<bits/stdc++.h> using namespace std; struct work { int a;//开始时间 int b;//结束时间 }f[2000]; bool cmp(work x, work y) { return x.b < y.b; } int main() { int n, sum = 1; int flag; cin >> n; for (int i = 0; i < n; i++) { cin >> f[i].a >> f[i].b; } sort(f, f + n, cmp);//按结束时间从小到大排序 flag = f[0].b; for (int i = 1; i < n; i++) { if (f[i].a >= flag) { sum++;//任意一个任务开始时间大于结束时间 兼容任务数+1 flag = f[i].b;//更新结束时间 } } cout << sum; return 0; }
Kunkun最近热爱rpg闯关游戏,经常带着他的舍友打各种boss。但是随着舍友装备的逐渐升级,kunkun发现他给予boss最后一击的机会越来越少(给boss最后一击的玩家稀有装备爆率会大幅度提升)。所以kunkun联系到了一个神秘人,他可以利用时停来让boss躲过舍友的攻击,每次时停只能躲避一次攻击。 假设kunkun和他的舍友都采取轮流攻击战术(kunkun率先攻击,kunkun的攻击力为a;舍友的攻击力为b,玩家每次都只进行一次攻击)去刷n个boss。如果最多只能使用k次时停,那么kunkun能造成致死伤害的boss最多有几个?
输入共两行。
第一行包括4个正整数 n,a,b,k (1≤n≤2*1e5, 1≤a,b,k≤1e9),n表示boss的数量,a为kunkun的攻击力,b为kunkun舍友的攻击力,k为时停的最大次数。
第二行输入n个正整数h1,h2,…,hn (1≤hi≤1e9),表示每个boss的血量。
输出一个整数,即kunkun造成致死伤害的boss的最大个数。
6 2 3 3
7 10 50 12 1 8
5
7 4 2 1
1 3 5 4 2 7 6
6
削减boss血线直到最后一次合击即可打死,判断此时血量需不需要时停。
若剩余血量恰好被攻击力a整除,则 时停次数 = 剩余血量 / a - 1;
若不能整除,则 时停次数 = 剩余血量 / a;
将时停次数从小到大排序,计算能杀死的boss数。
#include<bits/stdc++.h> using namespace std; int f[200000], g[200000];// f数组存boss剩余血量,g 数组存时所需停次数 int main() { int n, a, b, k, c; cin >> n >> a >> b >> k; for (int i = 0; i < n; i++) cin >> f[i]; c = a + b; for (int i = 0; i < n; i++) { if (f[i] % c == 0) f[i] = c; else f[i] = f[i] % c; }//boss经受kunkun与其舍友联合攻击后剩余血量(恰好kunkun + 舍友一次攻击可以致死) for (int i = 0; i < n; i++) { if (f[i] <= a) { g[i] = 0; }//若剩余血量小于kunkun攻击力,则不用时停,直接致死 else { if (f[i] % a == 0) g[i] = f[i] / a - 1; else g[i] = f[i] / a; }//否则算出所需时停数目 } sort(g, g + n);//将时停数从小到大排序 int ans = 0; for (int i = 0; i < n; i++) { k = k - g[i]; ans++; if (k < 0) { ans--; break; } }//遍历计算答案 cout << ans; return 0; }
输入一个自然数 n,对于一个最简分数 a/b(分子和分母互质的分数),满足 1≤b≤n,0≤a/b≤1,请找出所有满足条件的分数,并按分数值递增的顺序输出这些分数。
输入一个正整数 n(1≤n≤160)。
每个分数单独占一行,按照分数值递增的顺序排列。
5
0/1
1/5
1/4
1/3
2/5
1/2
3/5
2/3
3/4
4/5
1/1
两重循环遍历分子与分母,同时除以最大公约数(若分子分母均为偶数则必不互质,减少循环次数),再按分数值从小到大排序输出即可。
#include<bits/stdc++.h> using namespace std; int n, flag = -1; struct fenshu { int x;//分子 int y;//分母 double z;//分数值 }a[1000001]; int gcd(int x, int y) { return y == 0 ? x : gcd(y, x % y); }//求最大公约数 int cmp(fenshu x,fenshu y){ return x.z < y.z; } int main() { cin >> n; cout << "0/1" << endl;//输出最小 if (n != 1) { for (int i = 1; i <= n; i++) {//遍历分子 for (int j = i + 1; j <= n; j++) {//遍历分母 if (i % 2 == 0 && j % 2 == 0) continue;//偶数直接排除 else { int maxyue = gcd(i, j); flag++; a[flag].x = i / maxyue; a[flag].y = j / maxyue; a[flag].z = (i / maxyue * 1.0) / (j / maxyue * 1.0); } } } sort(a, a + flag, cmp);//按分数值从小到大排序 for (int i = 0; i <= flag; i++) { if (a[i].z != a[i + 1].z) { cout << a[i].x << "/" << a[i].y << endl; } } } cout << "1/1";//输出最大 return 0; }
最近,阿夸迷于德州扑克。所以她找到了很多人和她一起玩。由于人数众多,阿夸必须更改游戏规则:
所有扑克牌均只看数字,不计花色。
每张卡的值为1、2、3、4、5、6、7、8、9、10、11、12、13 中的一种(对应A,2、3、4、5、6、7, 8、9、10,J,Q,K)
每位玩家从一副完整的扑克牌(没有大小王)中抽出五张扑克牌,可能出现的手牌的值从低到高排列如下:
第一行包含一个正整数 N (1<=N<=100000) ,表示玩家的人数。
接下来 N 行,每行包含两个字符串:m (1<=|m|<=10 ) ,表示玩家的名字;s (1<=|s|<=10),表示玩家的手牌。
输出 N个玩家的排名列表。
3
Alice AAA109
Bob 678910
Boa 678910
Boa
Bob
Alice
设定 七位数 分值,设定每种牌型的底分,用函数解决每种牌型的判断,最后按分值输出即可。
#include<bits/stdc++.h> using namespace std; struct person { char name[20] = {'\0'};//名字 char pai[20] = { '\0' };//手牌 int num[15] = { -1,0,0,0,0,0,0,0,0,0,0,0,0,0,-1 };//每种牌的数目 int len = 0;//手牌长度 int score = 0;//等级分数 }a[100050]; int gaopai(person x) { int he = 0; for (int i = 1; i <= 13; i++) { he += i * x.num[i];//遍历手牌,算出所有手牌和; } x.score = he; if (x.score != 0) return x.score; else return 0; }//高牌 int dui(person x) { int duishu = 0; int dd[2] = { 0,0 }, j = 0;//dd数组表示对子的牌值 int he = 0;//剩余手牌之和 for (int i = 1; i <= 13; i++) { if (x.num[i] == 2) { duishu++; dd[j] = i; j++; }//若某种牌数量为2,对数增加,记录牌值 } if (duishu == 1) { for (int i = 1; i <= 13; i++) { if (i != dd[0]) he += i * x.num[i]; } x.score = 1000000 + dd[0] * 10000 + he *100; }//一对 if (duishu == 2) { for (int i = 1; i <= 13; i++) { if (i != dd[0] && i != dd[1]) he += i * x.num[i]; } x.score = 2000000 + dd[1] * 10000 + dd[0] * 100 + he; }//两对 if (x.score != 0) return x.score; else return 0; }//对子(一对,两对) int tiao(person x) { int tiaoshu = 0; int k = 0;//标记 int nn = 0, mmm = 0;//nn记录对子的值,mmm记录条的值 int he = 0;//记录剩余手牌和 for (int i = 1; i <= 13; i++) { if (x.num[i] == 2) { k = 1; nn = i; }//若手牌中有对子,则记录对子的值 if (x.num[i] >= 3) { tiaoshu = x.num[i]; mmm = i; }//记录条数与条值 } for (int i = 1; i <= 13; i++) { if (i != mmm) { he += i * x.num[i]; } }//计算剩余手牌和 if (tiaoshu == 3) { if (k == 1) { x.score = 4000000 + mmm * 10000 + nn * 100; }//若有对子,则为满堂红 else { x.score = 3000000 + mmm * 10000 + he * 100; }//只有三条 }//含三条的情况 if (tiaoshu == 4) { x.score = 5000000 + mmm * 10000 + he * 100; }//四条 if (tiaoshu == 5) { x.score = 5000000 + mmm * 10000 + mmm * 100; }//本题最后两个测试点含5张牌一样的情况 if (x.score != 0) return x.score; else return 0; }//条(三条 满堂红 四条) int shun(person x) { for (int i = 1; i <= 9; i++) { if (x.num[i] == 1 && x.num[i + 1] == 1 && x.num[i + 2] == 1 && x.num[i + 3] == 1 && x.num[i + 4] == 1) { x.score = 6000000 + i * 10000; } }//暴力判断,起始手牌从1-9 if (x.score != 0) return x.score; else return 0; }//顺子 int huangjia(person x) { if (x.num[1] == 1 && x.num[10] == 1 && x.num[11] == 1 && x.num[12] == 1 && x.num[13] == 1) x.score = 7000000;//暴力判断10 J Q K A if (x.score != 0) return x.score; else return 0; }//皇家同花顺 int cmp(person x,person y) { if (x.score == y.score) return strcmp(x.name, y.name) < 0; else return x.score > y.score; }//sort的比较(先按分数值从大到小排列 在分数值相同情况下按字典序输出玩家名字) int main() { int n; cin >> n; for (int i = 0; i < n; i++) { scanf("%s %s", a[i].name, a[i].pai); a[i].len = strlen(a[i].pai); }//输入手牌并计算手牌长度 for (int i = 0; i < n; i++) { for (int j = 0; j < a[i].len; j++) { if (a[i].len > 5) a[i].num[10] = a[i].len - 5;//若手牌长度大于5,则说明含10 if (a[i].pai[j] == 'A') a[i].num[1]++; if (a[i].pai[j] == '2') a[i].num[2]++; if (a[i].pai[j] == '3') a[i].num[3]++; if (a[i].pai[j] == '4') a[i].num[4]++; if (a[i].pai[j] == '5') a[i].num[5]++; if (a[i].pai[j] == '6') a[i].num[6]++; if (a[i].pai[j] == '7') a[i].num[7]++; if (a[i].pai[j] == '8') a[i].num[8]++; if (a[i].pai[j] == '9') a[i].num[9]++; if (a[i].pai[j] == 'J') a[i].num[11]++; if (a[i].pai[j] == 'Q') a[i].num[12]++; if (a[i].pai[j] == 'K') a[i].num[13]++; }//记录手牌中每种牌的张数 int ss[5];//用于判断牌型并记录分值 ss[0] = gaopai(a[i]); ss[1] = dui(a[i]); ss[2] = tiao(a[i]); ss[3] = shun(a[i]); ss[4] = huangjia(a[i]); sort(ss, ss + 5);//原始sort函数,将数组中数据按非降序排列 a[i].score = ss[4]; }//计算分值 sort(a, a + n, cmp);//按自定义排序排列分数 for (int i = 0; i < n; i++) { if (i != n - 1) printf("%s\n", a[i].name); else printf("%s", a[i].name); }//输出结果 return 0; }
二维平面上,对于坐标分别为(x1 , y1)和(x2 , y2)的两点 p、q,它们之间的曼哈顿 距离为 | x1 - x2 | + | y1 - y2 |。 给出 n 个点,猫日的作业是计算出这 n 个点中每两点之间的曼哈顿距离。但是,猫日只会计算点和点之间的直线距离。如果猫日每答对一题可以获得一块小鱼干,那么它最后能蒙对多少题?拿到多少小鱼干呢?
第一行包括一个正整数 n(1<=n<=50000)。
接下来有 n 行,每行两个正整数 xi 和 yi表示二维平面上点的坐标。
输出一个整数,为猫日蒙对的题数。数据保证答案在 int 范围内。
3
1 1
7 5
1 5
2
遍历任意两个点,若这两个点的x相同或者y相同则这两点曼哈顿距离等于直线距离。
#include<bits/stdc++.h> using namespace std; struct dian { int x; int y; }a[50050]; int main() { int n; cin >> n; int ans = 0; for (int i = 0; i < n; i++) { cin >> a[i].x >> a[i].y; } for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (a[i].x == a[j].x || a[i].y == a[j].y) { ans++; } } } cout << ans; return 0; }
现在有两个不同的日期,你能告诉我它们之间差几天吗?
有多行数据,每行数据包含6个数字,中间用空格分隔,每3个数字代表一个日期。
对应于输入数据,输出数据有相同的行数,每行表示对应的两个日期相差的天数。
1934 2 4 2047 11 30
2192 10 3 1921 5 8
-41572
99130
#include<stdio.h> int main() { int run(int y1); int month(int y1, int m1, int d1); int y1, y2, m1, m2, d1, d2; while (scanf("%d %d %d %d %d %d", &y1, &m1, &d1, &y2, &m2, &d2) != EOF) { if (y1 == y2) { printf("%d\n", month(y1, m1, d1) - month(y2, m2, d2)); } if (y1 < y2) { long long int days = 0; if (run(y1)) days -= (long long int)366 - month(y1, m1, d1); else days -= (long long int)365 - month(y1, m1, d1); for (y1++; y1 != y2; y1++) { if (run(y1)) days -= 366; else days -= 365; } days -= month(y2, m2, d2); printf("%lld\n", days); } if (y1 > y2) { long long int days = 0; if (run(y2)) days += (long long int)366 - month(y2, m2, d2); else days += (long long int)365 - month(y2, m2, d2); for (y2++; y1 != y2; y2++) { if (run(y2)) days += 366; else days += 365; } days += month(y1, m1, d1); printf("%lld\n", days); } } return 0; } int month(int y1, int m1, int d1) { int a = 0; int run(int y1); if (run(y1)) { switch (m1) { case 1:break; case 2:a += 31; break; case 3:a += 31 + 29; break; case 4:a += 31 + 29 + 31; break; case 5:a += 31 + 29 + 31 + 30; break; case 6:a += 31 + 29 + 31 + 30 + 31; break; case 7:a += 31 + 29 + 31 + 30 + 31 + 30; break; case 8:a += 31 + 29 + 31 + 30 + 31 + 30 + 31; break; case 9:a += 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31; break; case 10:a += 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30; break; case 11:a += 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; break; case 12:a += 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30; break; } a += d1; } else { switch (m1) { case 1:break; case 2:a += 31; break; case 3:a += 31 + 28; break; case 4:a += 31 + 28 + 31; break; case 5:a += 31 + 28 + 31 + 30; break; case 6:a += 31 + 28 + 31 + 30 + 31; break; case 7:a += 31 + 28 + 31 + 30 + 31 + 30; break; case 8:a += 31 + 28 + 31 + 30 + 31 + 30 + 31; break; case 9:a += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; break; case 10:a += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; break; case 11:a += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; break; case 12:a += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30; break; } a += d1; } return a; } int run(int y1) { return (y1 % 4 == 0 && y1 % 100 != 0) || (y1 % 100 == 0 && y1 % 400 == 0); }
给定一个包含n个数的数列,由a1,a2,…,an组成,现在将这n个数分成若干组,使得每组中任意两个数|ai-aj|>1,(i!=j)。这个数列中的n个数最少可以分成几组呢?
第一行包含一个整数n(1≤n≤1000)。 第二行包含n个整数a1,a2,…,an(1≤ai≤10000,所有ai互不相同)。
输出仅一个整数,表示数列中n个数最少可以分成的组数。
2
1 2
2
数组排序,计算相邻两数之差,若含差大于1的两个数,则分为两组,否则分为1组。
#include<bits/stdc++.h> using namespace std; int main(){ int n; int flag=0; int a[1010]; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n); for(int i=1;i<n;i++){ if(a[i]-a[i-1]==1) flag=1; } if(flag) cout<<2; else cout<<1; return 0; }
小明是个普通的计算机本科生,很喜欢研究数组相关的问题。在他的认知里,美丽的数组是这样的,对于一个长度为n的数组a,存在一个下标i(1<=i<=n)使得1i之间的数是严格递增的,i+1n之间的数是严格递减的。现在这个数组a里的元素是随机给定的(这个数组可能是不美丽的),对于数组a内的任意一个元素ai我们可以进行若干次ai=ai-1(ai>0)的操作,问能否通过若干次操作使得这个数组变得美丽。
第一行输入数组长度n (1≤n≤3*1e5), 第二行输入n个整数a1,…,an (0≤ai≤1e9)。
输出“Yes”表示这个数组可以变美丽,输出“No”表示不可以。
3
1 0 1
No
遍历数组,若a[i]>=i,则a[i]=i,以此构造递增数列;
若a[i]<i,则此时a[i]为递减数列的起始,之后的a[i]=a[i-1]-1,若某个a[i]<0,则不能构成美丽数列,反之若能遍历完数组,则可以构成美丽数列。
#include<bits/stdc++.h> using namespace std; int a[300050]; int main() { int n; cin>>n; for (int i=0;i<n;i++){ cin>>a[i]; } int i=0; for (i=0;i<n;i++){ if (a[i]>i) a[i]=i; if (a[i]<i) break; } for (i=i+1;i<n;i++){ if (a[i-1]<a[i]) a[i]=a[i-1]-1; if (a[i]<0){ cout<<"No"; return 0; } } cout<<"Yes"; return 0; }
给定两个字符串a、b,现有k次机会对字符串中的字符进行修改,使修改后两个字符串的最长公共子串最长。每一次修改,可以选择a、b字符串中某一个串的任意位置修改成任意字符。
第一行包括一个正整数 k。
第二行和第三行分别输入字符串a、b。(每个串的长度不超过500)
输出为一个整数,表示修改后的两个串的最长公共子串长度。
5
aaaaa
bbbbb
5
遍历数据,直到有k个不一样的字符时,结束,比较长度,存储最长的一条。
#include<bits/stdc++.h> using namespace std; int main(){ string a,b; int k; cin>>k; getchar(); getline(cin,a); getline(cin,b); int l1=a.length(); int l2=b.length(); int ans=-1; for(int i=0;i<l1;i++){ for(int j=0;j<l2;j++){ int step=0,cuo=k; for(int m=i,n=j;m<l1&&n<l2;m++,n++){ if(a[m]==b[n]){ step++; } if(a[m]!=b[n]){ if(cuo>0){ step++; cuo--; } else break; } } ans=max(ans,step); } } printf("%d",ans); return 0; }
玛莎有n个骰子,每个骰子的6个面上都恰好有一个0到9之间的数字。
现在玛莎将利用这n个筛子来制作新数字。她把n个骰子摆成一排,然后从左到右查看骰子的上表面并读取,即可得到一个新数字。随后她不断的旋转每个骰子的面就可以得到不同的新数字。旋转骰子需要满足以下规则: 1、制作的数字不能包含前导零; 2、制作新数字时不需要使用所有的骰子; 3、使用骰子旋转,无法将数字9转换为数字6,反之亦然。
给定n个骰子,玛莎可以用它们构成从1到x的所有整数。玛莎想知道,对于给定的n个骰子,这个x的最大取值是多少呢?
第一行仅一个整数n,表示骰子的数量(1≤n≤3)。
接下来n行,每行包含6个整数a[i][j](0≤a[i][j]≤9),表示第i个骰子的第j个面上的数字。
输出一个整数,即最大数x,玛莎可以使用她的骰子构成数字从1到x。如果无法构成1,则输出0。
3
0 1 3 5 6 8
1 2 4 5 7 8
2 3 4 6 7 9
98
首先,骰子一共最多只有18个数字,最大只能达到98;所以只要从1开始遍历到98即可;
判断1-9时:双重循环遍历所有骰子的所有面,查找数字。
判断10-98时:双重循环遍历所有骰子,查找十位数字,存在时,再双重循环遍历剩余骰子所有面,查找个位数字。
#include<bits/stdc++.h> using namespace std; int a[3][6]; int main() { int n; cin >> n; for (int i = 0; i < n; i++) { for (int j = 0; j < 6; j++) { cin >> a[i][j]; } } int i, x, y, z, w; for (i = 1; i <= 99; i++) { int flag = 0; if (i < 10) { for (x = 0; x < n; x++) { for (y = 0; y < 6; y++) { if (a[x][y] == i) { flag = 1; } } } } else { int aa = i / 10; int bb = i % 10; for (x = 0; x < n; x++) { for (y = 0; y < 6; y++) { if (a[x][y] == aa) { for (z = 0; z < n; z++) { if (z != x) { for (w = 0; w < 6; w++) { if (a[z][w] == bb) { flag = 1; } } } } } } } } if (flag == 0) { cout << i - 1; return 0; } } }
n个人围成一圈,每人有ai支笔。每人可以向左右相邻的人传递笔,每人每次传递一支笔消耗的能量为1。求使所有人获得均等数量的笔的最小能量。
第一行一个整数n ,表示人的个数(30%的数据,n<=1000;100%的数据,n<=1e6)。
接下来n行,每行一个整数 ai。
输出一个整数,表示使所有人获得均等笔的最小能量。(答案保证可以用64位有符号整数存储)
4
1
2
5
4
4
首先,计算平均值,用ave表示。
假设标号为i的小朋友开始有Ai颗糖果,Xi表示第i个小朋友给了第i-1个小朋友Xi颗糖果,如果Xi<0,说明第i-1个小朋友给了第i个小朋友Xi颗糖果,X1表示第一个小朋友给第n个小朋友的糖果数量。 所以最后的答案就是ans=|X1| + |X2| + |X3| + ……+ |Xn|。 对于第一个小朋友,他给了第n个小朋友X1颗糖果,还剩A1-X1颗糖果;但因为第2个小朋友给了他X2颗糖果,所以最后还剩A1-X1+X2颗糖果。根据题意,最后的糖果数量等于ave,即得到了一个方程:A1-X1+X2=ave。
同理,对于第2个小朋友,有A2-X2+X3=ave。最终,我们可以得到n个方程,一共有n个变量,但是因为从前n-1个方程可以推导出最后一个方程,所以实际上只有n-1个方程是有用的。
尽管无法直接解出答案,但可以用X1表示出其他的Xi,那么本题就变成了单变量的极值问题。
对于第1个小朋友,A1-X1+X2=ave >>> X2=ave-A1+X1 = X1-C1(假设C1=A1-ave,下面类似)
对于第2个小朋友,A2-X2+X3=ave >>> X3=ave-A2+X2=2ave-A1-A2+X1=X1-C2
对于第3个小朋友,A3-X3+X4=ave >>> X4=ave-A3+X3=3ave-A1-A2-A3+X1=X1-C3
对于第n个小朋友,An-Xn+X1=ave。
我们希望Xi的绝对值之和尽量小,即|X1| + |X1-C1| + |X1-C2| + ……+ |X1-Cn-1|要尽量小。注意到|X1-Ci|的几何意义是数轴上的点X1到Ci的距离,所以问题变成了:给定数轴上的n个点,找出一个到他们的距离之和尽量小的点,而这个点就是这些数中的中位数。
来源:洛谷P2512
#include <bits/stdc++.h> using namespace std; long long a[1000010],b[1000010]; int main() { long long n,sum=0,avg=0; cin>>n; for(int i=0;i<n;i++){ cin>>a[i]; sum+=a[i]; } avg=sum/n; b[0]=a[0]-avg; for(int i=1;i<n;i++) b[i]=b[i-1]+a[i]-avg; sort(b,b+n); long long min=0; for(int i=0;i<n;i++) min+=abs(b[n/2]-b[i]); cout<<min; return 0; }
郭老师有草莓和山楂两种水果共计n个,她打算用这些水果做一串冰糖葫芦。她会把这串冰糖葫芦的水果组成用字符串的形式告诉你,其中’B’表示草莓,’W’表示山楂,例如:BBW,表示这串冰糖葫芦的水果按照顺序是草莓、草莓、山楂。郭老师想知道这串冰糖葫芦上的草莓串有几串,按照从左到右的顺序,这些草莓串的长度分别是多少?例如,冰糖葫芦WBBBBWWBWBBBW中共有3个草莓串它们的长度分别是4、1、3。
第一行包含一个整数为n (1 ≤ n ≤ 100),表示郭老师拥有的水果总数。 第二行为一串只包含字符’B’和’W’的字符串,即糖葫芦的水果组成。
第一行输出一个整数,表示糖葫芦中包含的草莓串个数。 第二行有多个整数,分别表示糖葫芦中按从左到右顺序各个草莓串中草莓的个数。
13
WBBBBWWBWBBBW
3
4 1 3
#include<iostream> using namespace std; int main() { char a[150]={"\0"}; int n; int len[150]={0}; cin >> n; scanf("%s", a); int sum = 0; int k = 0, j, i; for (i = 0; i < n;i++) { if (a[i] == 'B') { len[k] = 1; sum++; for (j = i + 1; j < n&&a[j]!='W'; j++) { if (a[j] == 'B') len[k]++; } i = j; k++; } } cout << sum << endl; for (int i = 0; i < k; i++) { cout << len[i] << " "; } return 0; }
你是一个bilibili的六级号,由于经常一键三连,所以一个硬币都没有,现在你做了个梦,在梦中你制定了一个投币规则: 一个用户共有s个币,他每次选择x个硬币投出去(1<=x<=s),并且会得到x/10(向下取整)的找零。用户一直重复这个过程,最终把所有的硬币全都投完。按照这个规则,用户可以达到的最大投币数是多少呢?
举个例子,如果你有19个币,一开始,你投了10个币,得到1一个币的找零,然后你又投了10个币,得到1个币的找零,最后你把这1个币也投出去。这样你就可以达到最大投币数21。
第一行包含一个整数t(1<=t<=10^4),表示有t个用户。
接下来的t行,每行一个整数,表示某个用户的硬币数s(1<=s<=10^9)。
输出t行,每行一个整数,表示对应用户最多能投出的硬币数。
6
1
10
19
9876
12345
1000000000
1
11
21
10973
13716
1111111111
由题意可知,整10的硬币数投入,收益最大。
#include<iostream> using namespace std; int main() { int t; cin >> t; while (t--) { int s; int sum = 0; cin >> s; while (s>=10) { sum += s - s % 10; s = (s - s % 10) / 10 + s % 10; } sum += s; cout << sum << endl; } return 0; }
伊戈尔发现有一家商店正在打折,所以决定在这家商店购买n件商品。商店的打折活动会持续一周,打折期间每件商品的价格是ai,等打折活动结束后,商品的价格变为bi。但是并非所有卖家都诚实,因此打折期间某些商品的价格可能会比折扣活动结束后的价格更贵。
伊戈尔决定现在至少购买k件商品,剩下的商品等活动结束后再购买。你的任务是帮伊戈尔计算一下用于购买n件商品的最低费用。
第一行包含两个正整数n和k(1≤n≤2e5,0≤k≤n),分别表示伊戈尔要购买的商品数量和他现在只少要买的商品数。
第二行包含n个整数 a1,a2,…,an(1≤ai≤1e4),分别表示折扣期间各个商品的价格。
第三行包含n个整数 b1,b2,…,bn(1≤bi≤1e4),分别表示折扣结束后商品的价格。
伊戈尔购买n件商品所需的最低金额。
3 1
1 3 5
6 4 2
6
建立结构体(分别为折扣价,原价,差价),遍历所有商品;
若折扣价低于原价直接买入,必买商品数-1,差价与原价置为0;
若折扣价高于原价,则计算差价;
将所有商品的非0差价按从小到大排序,差价为0的后置;
若此时必买商品数为0,则将剩下的原价商品买入;
若不为0,则按排序后的商品买入折扣价商品,并将原价置为0,直到必买商品数为0时;此时再将所有原价商品买入。
#include<bits/stdc++.h> using namespace std; struct goods{ int a;//折扣价 int b;//原价 int c;//差价 }f[10000]; int cmp(goods x, goods y){ if(x.c!=0&&y.c!=0) return x.c<y.c; else return x.c>y.c; }//非0的差价按从小到大排序 int main(){ int n, k; int sum=0; cin>>n>>k; for (int i = 0; i < n; i++){ cin>>f[i].a; } for (int i = 0; i < n; i++){ cin>>f[i].b; } for (int i = 0; i < n; i++){ if (f[i].a <= f[i].b){ sum += f[i].a; f[i].c = 0; f[i].b = 0; k--; } else f[i].c = f[i].a - f[i].b; } sort(f,f+n,cmp); if(k<=0){ for(int i=0;i<n;i++){ sum+=f[i].b; } cout<<sum<<endl; return 0; } else{ for(int i=0;i<n&&k>0;i++,k--){ sum+=f[i].a; f[i].b=0; } for(int i=0;i<n;i++){ sum+=f[i].b; } cout<<sum<<endl; return 0; } }
对于一个自然数n,若将n的各位数字反向排列所得的数n1与n相等,则称n为回文数,例如2332。
若给定一个N( 2<=N<=16)进制数M(M的长度在一百位以内),如果M不是回文数,可以对其进行N进制加法,最终得到回文数。
例如对于十进制数79 STEP1 : 79 + 97 = 176 STEP2 : 176 + 671 = 847 STEP3 : 847 + 748 = 1595 STEP4 : 1595 +5951 = 7546 STEP5 : 7546 + 6457 = 14003 STEP6 : 14003 + 30041 = 44044
那么对于给定的N进制数M,请判断其能否在30步以内(包括30步)得到回文数。
第一行包括一个正整数 N(2<=N<=16)。
第二行包括一个正整数M(一百位以内)。
如果可以在n步内得到回文数,输出“STEP=n”,否则输出“NO”。
10
79
STEP=6
8
665556
NO
题目难点在于n进制加法如何表示,按题目意思,将数组正序与逆序的各位上数字相加即可得到结果,按照竖式计算的步骤进行,注意10进制以上的数字需要特别表示。用一个函数判断此时数据是否是回文数。
#include<bits/stdc++.h> using namespace std; int n, m, len=0, step=0, a[10000]; string x; int judge(int len){ for (int i = 0; i <= len / 2; i++) if (a[i] != a[len - i - 1]) return 0; return 1; }//判断回文数 int fun(int len){ int c[10000] = { 0 }, k = 0; for (int i = 0; i < len; i++) { c[i] = a[i] + a[len - i - 1] + c[i];//正序逆序各位数字相加 c[i + 1] += c[i] / n; //进位 c[i] %= n; } if (c[len] != 0) len++;//更新数组长度 for (int i = len - 1; i >= 0; i--) { a[k++] = c[i];//逆序更新数字 } return len; } int main(){ cin >> n; cin >> x; len = x.length(); for (int i = 0; i < len; i++){ if (x[i] < 'A') a[i] = x[i] - '0'; else a[i] = x[i] - 'A' + 10; } if(judge(len)){ cout<<"STEP=0"<<endl; return 0; } while (step <= 30){ step++; len = fun(len); if (judge(len)) { cout << "STEP=" << step << endl; return 0; } } cout << "NO" << endl; return 0; }
楼梯有N阶,上楼可以一步上一阶,也可以一步上两阶。那么走到第N阶楼梯共有多少种不同的走法呢?
一个正整数 N(1<=N<=5000),表示楼梯阶数。
输出一个数,表示走到第N阶楼梯有多少种走法。
注意,数据范围很大,即使是64位也可能不够存。
4
5
400
284812298108489611757988937681460995615380088782304890986477195645969271404032323901
二维数组f[x][i],储存每一级阶梯f[x]走法的种类数;
其f[x]满足f[1]=1,f[2]=2,f[x]=f[x-1]+f[x-2]的递推公式;
所以可将问题转化为高进度加法。
#include<bits/stdc++.h> #define MAXN 5050 using namespace std; int len = 1; int f[MAXN][MAXN]; void fun(int x) { for (int i = 0; i < len; i++) { f[x][i] = f[x - 1][i] + f[x - 2][i]; } for (int i = 0; i < len; i++) { if (f[x][i] > 9) { f[x][i + 1] += f[x][i] / 10; f[x][i] = f[x][i] % 10; } if (f[x][len] != 0) len++; } } int main() { int n; cin >> n; f[1][0] = 1; f[2][0] = 2; for (int i = 3; i <= n; i++) { fun(i); } for (int i = len-1; i >= 0; i--) { cout << f[n][i]; } }
已知两个数A和B,求A-B的运算结果。
输入包括两个正整数A和B 。(0<A,B≤1e10086)
输出A-B的运算结果。
3
2
1
11102356985410
2356985410235698
-2345883053250288
高精度减法,模拟竖式运算。
#include<bits/stdc++.h> #define MAXN 1000086 using namespace std; string a, b; int na[MAXN], nb[MAXN], ans[MAXN]; int main() { int flag = 0; cin >> a >> b; if((a < b && a.size() == b.size()) || a.size() < b.size()){ swap(a, b); flag = 1; } for(int i = a.size(); i > 0; i --) na[i] = a[a.size() - i] - '0'; for(int i = b.size(); i > 0; i --) nb[i] = b[b.size() - i] - '0'; int maxl = max(a.size(), b.size()); for(int i = 1; i <= maxl; i ++){ if(na[i] < nb[i]){ na[i + 1] --; na[i] += 10; } ans[i] = na[i] - nb[i]; } while(ans[maxl] == 0) maxl --; if(flag == 1) cout << "-"; for(int i = maxl; i > 0; i --) cout << ans[i]; if(maxl < 1) cout << "0"; return 0;
给两个正整数 a,b,求 a/b的整数部分。
输入共两行,每行一个正整数,分别表示 a和b。 50%数据,a,b均小于1e18, 50%数据,a,b均小于1e500。
输出一个整数,表示a/b的整数部分。
##输入样例1:
3
2
1
24781236498237462378425347823652387423654238752372365327862
8934457724628746
2773669903874014740488146558678531750078864
高精度除法,用减法代替除法运算。
#include<bits/stdc++.h> using namespace std; int a[1000], b[1000], c[1000];//a存被除数与余数;b存除数;c存整除结果 string aa, bb; int compare(int a[], int b[]) { if (a[0] > b[0]) return 1; if (a[0] < b[0]) return -1; if (a[0] == b[0]) { for (int i = a[0]; i > 0; i--) { if (a[i] > b[i]) return 1; if (a[i] < b[i]) return -1; } return 0; } }//a<b为-1,a>b为1,a=b为0 void move(int b[], int tmp[], int w) { for (int i = 1; i <= b[0]; i++) { tmp[w + i - 1] = b[i]; } tmp[0] = b[0] + w - 1; }//将除数b右移,存于tmp中; void jian(int a[], int tmp[]) { int pd, i; pd = compare(a, tmp); if (pd == 0) { a[0] = 0; } if (pd == 1) { for (i = 1; i <= a[0]; i++) { if (a[i] < tmp[i]) { a[i + 1]--; a[i] += 10; a[i] -= tmp[i]; } else { a[i] -= tmp[i]; } } while ((a[a[0]] == 0) && a[0] > 0) a[0]--; } } void chufa(int a[], int b[], int c[]) { int i; int tmp[1000];//存除数与被除数对齐的结果 c[0] = a[0] - b[0] + 1;//c[0]存整除结果的长度 for (i = c[0]; i > 0; i--) { memset(tmp, 0, sizeof(tmp)); move(b, tmp, i); while (compare(a, tmp) >= 0) { c[i]++; jian(a, tmp); } } while ((c[c[0]] == 0) && c[0] > 0) c[0]--; } int main(){ int pd; cin >> aa; a[0] = aa.length();//a[0]存数组长度 for (int i = 01; i <= a[0]; i++) { a[i] = aa[a[0] - i] - '0'; } cin >> bb; b[0] = bb.length();//b[0]存数组长度 for (int i = 1; i <= b[0]; i++) { b[i] = bb[b[0] - i] - '0'; } //输入 pd = compare(a, b); if (pd == -1) { cout << 0 << endl; } if (pd == 0) { cout << 1 << endl; } if (pd == 1) { chufa(a, b, c); for (int i = c[0]; i > 0; i--) { cout << c[i]; } } return 0; }
给你一个混排的数列,其中包含x的所有除数(包括1和x)和y的所有除数(包括1和y)。如果d同时是x和y的除数,则列表中d将会出现两次。
例如,x = 4,y = 6,则给定列表可以是列表[1,2,4,1,2,3,6]的任何排列。一些可能的列表是:[1,1,2,4,6,3,2],[4,6,1,1,2,3,2]或[1,6,3,2,4,1,2]。
现在给定一个数列,它是某两个正整数x和y的所有除数列表。请你帮忙找出这两个正整数x和y。
第一行包含一个整数n(2≤n≤128),表示数列包含的数的个数。
第二行包含n个整数d1,d2,…,dn(1≤di≤10^4),其中di是x的除数或y的除数。如果一个数字同时是x和y的除数,则数组中有两个该数字。
输入保证答案存在。
输出仅一行,包含两个正整数x和y (x>=y),以空格分隔。
10
10 2 8 1 2 4 1 20 4 5
20 8
记录x,y所有除数的值,统计每个值出现的次数,把所有除数按从小到大排列,则最大的数即为x;再遍历数组,把是x除数且出现次数不为0的值置为0,且将出现次数置为0;保证将x除数消去的同时,只将x,y的公约数消去一个,再次排序,此时最大值即为y。
#include<bits/stdc++.h> using namespace std; int main() { int n; int a[200], b[10050] = { 0 }; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i]; b[a[i]]++; } sort(a, a + n); int x, y; x = a[n - 1]; for (int i = 0; i < n; i++) { if (a[i] != 0 && x % a[i] == 0) { if (b[a[i]] != 0) { b[a[i]] = 0; a[i] = 0; } } } sort(a, a + n); y = a[n - 1]; cout << x << " " << y; return 0; }
卡罗拉最近沉迷于ark游戏,游戏中的地图上有n个浮空的石头围成了一圈,在优秀的物理引擎支持下,这些石头会自动落下。她发现石头落下的顺序是有规律的。一共有n个石头,从第一块石头开始数,数到第m个石头,那块就是第一个落下的石头;之后从第一个落下的石头后一个重新从1开始数,同样数到第m个石头,那个就是第二个落下的石头;以此类推。为了方便,对这些石头从1开始编号。卡罗拉现在想知道最后落下的是那一块石头?
输入包含两个整数n和m (1<=m,n<=1000)。
输出一 个整数,代表最后落下的石头的编号。
10 3
4
约瑟夫环问题,用链表将所有数据连接成环。
#include<bits/stdc++.h> using namespace std; struct person { person* former; int num; person* latter; }a[1050]; void out(person* now) { now->former->latter = now->latter; now->latter->former = now->former; } int main() { int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { a[i].num = i; if (i != n && i != 1) { a[i].latter = &a[i + 1]; a[i].former = &a[i - 1]; } } a[n].former = &a[n - 1]; a[n].latter = &a[1]; a[1].former = &a[n]; a[1].latter = &a[2]; //初始化链表 person* now = &a[1]; int k = 1; int nownumber = 1; while (n) { if (nownumber == m) { if (n == 1) cout << now->num << endl; k++; out(now); nownumber = 1; n--; now = now->latter; } else { nownumber++; now = now->latter; } } return 0; }
h学长有个机器用来完成任务。现在有n个任务,第i个任务(1<= i <= n)在ti时刻开始,并在ti + 1时刻结束。同一时刻不会有多个任务。 h学长可以在任何时刻开启机器,不过每一次开启机器都会消耗1点能量。h学长只有k点能量可以用于开启机器。但是机器开着的时候需要消耗燃料,显然让机器一直开着并不一定是最好的选择。现在h学长想利用自己具备的k点能量,有效的控制机器的开启,使得机器完成n个任务消耗的燃料尽可能的少。那么对应给出的n个任务以及h学长拥有的能量数,你能帮帮他吗? 提示:消耗的燃料要尽可能的少,即机器工作的时间尽可能的短。
第一行包括两个整数 n和k(1<= n <= 1e5, 1<= k <=n) ,表示有 n个任务和h学长拥有k点能量。
接下来 n行,每行一个整数ti(1<= ti <=1e9),表示第 i 个任务在ti 时刻开始,并在ti + 1时刻结束 。
输出一行包含一个整数,表示机器工作的最少时间。
输入样例1:
3 2
1
3
6
4
样例1说明:
h学长有2点能量,可以用于两次机器的开启。 h学长会在时刻1 即第一个任务开始时开启机器,并在第二个任务结束时关闭机器; h学长会在时刻6 即第三个任务开始时开启机器,并在第三个任务结束时关闭机器。 机器总工作时间为 (4-1)+(7-6)=4 。
10 5
1
2
5
6
8
11
13
15
16
20
12
样例2说明:
h学长有5点能量,可以用于5次机器的开启。 h学长会在时刻1 即第1个任务开始时开启机器,并在第2个任务结束时刻3关闭机器; h学长会在时刻5 即第3个任务开始时开启机器,并在第4个任务结束时刻7关闭机器; h学长会在时刻8 即第5个任务开始时开启机器,并在第5个任务结束时刻9关闭机器; h学长会在时刻11 即第6个任务开始时开启机器,并在第9个任务结束时刻17关闭机器; h学长会在时刻20 即第10个任务开始时开启机器,并在第10个任务结束时刻21关闭机器; 机器总工作时间为 (3-1)+(7-5)+(9-8)+(17-11)+(21-20)=12 。 开机、关机时刻不唯一。
将两相邻任务的间隔时间排序,将开机次数用再间隔时间最长的任务中。
#include<bits/stdc++.h> using namespace std; int a[100050], b[100050]; int main() { int n, k; cin >> n >> k; for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < n - 1; i++) { b[i] = a[i + 1] - a[i] - 1; } sort(b, b + n - 1); int sum = 0; for (int i = 0; i < n - k; i++) { sum += b[i]; } cout << sum + n; return 0; }
小明的工作是对一串英语字符进行特殊的翻译:当出现连续且相同的小写字母时,须替换成该字母的大写形式,在大写字母的后面紧跟该小写字母此次连续出现的个数;与此同时,把连续的小写字母串的左侧和右侧的字符串交换位置;重复该操作,直至没有出现连续相同的小写字母为止。现在小明想请你帮他完成这种特殊的翻译。
输入一串由小写字母构成的字符串。(字符串长度不大于250)
输出翻译后的字符串。
dilhhhhope
opeH4dil
lodnkmgggggggoplerre
eG7lodnkmR2ople
遍历字符串,若遇到连续的小写字母则记录下第一个的下标j;
循环计算连续小写字母的长度,记下最后一个的下标i(此时相同字符长度为j到i);
将相同字符之后的字符串,也就是i以后的字符用substr函数返回并用append函数连接到一个空字符串s中,将此时的相同字符转化为一个大写字母用append函数连接到s中,再用sprintf函数将整型数字i-j+1转化为字符型储存并连接到s中,再将0到j的子字符串连接到s之后,完成前后倒置。
循环以上操作,直到字符串中没有连续的小写字母为止。
#include<bits/stdc++.h> using namespace std; string a, s; char s1[1000]; int i, j; bool f; int main(){ cin >> a; while (1) { f = false; while (a[i] != a[i + 1] && a[i + 1] != 0 && a[i] >= 'a' && a[i] <= 'z') i++; j = i; while (a[i] == a[i + 1] && a[i + 1] != 0 && a[i] >= 'a' && a[i] <= 'z'){ i++; f = true; }//出现连续小写字母 if (f == false) break;//若不出现连续小写字母则跳出循环 if (i < a.length()) s.append(a.substr(i + 1));//substr返回i+1之后的所有字符,再用append连接到s中 string str1(1, a[i] - 32);//将小写的a[i]转化为大写字母存放入字符串str1中 s.append(str1);//将str1连接到s末尾 sprintf(s1, "%d", i - j + 1);//将整型数字i-j+1转化为字符型存放在字符数组s1中 string str2(s1);//构造s1为string型str2 s.append(str2);//将str2连接到s末尾 if (j > 0) s.append(a.substr(0, j));//将连续小写字母之前的所有字符连接到s末尾,完成倒置 a = s;//a赋值为新生成的字符串s s = "";//s置空 i = 0; j = 0; } cout << a; return 0; }
超市正在特价售卖巧克力,正好被贪吃的Lucky_dog看见了。
巧克力从左到右排成一排,一共有N个,M种。
超市有一个很奇怪的规定,就是你在购买巧克力时必须提供两个数字a和b,代表你要购买第 a 个至第 b 个巧克力(包含 a 和 b)之间的所有巧克力。
假设所有巧克力的单价均为1元。Lucky_dog想吃所有种类的巧克力,但又想省钱。作为Lucky_dog的朋友,他请你来帮他决定如何选择购买巧克力时的 a 和 b。
第一行包含两个正整数 N 和 M(M<=N, N<=10^6 , M<=2000),分别代表巧克力的总数及种类数。
第二行包含 N 个整数,这些整数均在1 至 M 之间,代表对应的巧克力所属的种类。
输出仅一行,包含两个整数a和 b(a<=b) ,由一个空格隔开,表示花费最少且包含所有种类巧克力的购买区间。
数据保证有解,如果存在多个符合条件的购买区间,输出a最小的那个。
12 5
2 5 3 1 3 2 4 1 1 5 4 3
2 7
用a数组储存每个巧克力,用b数组储存区间LR中每种巧克力有几个,遍历数组,右移右端点R直到出现的巧克力种类数等于m。(确定右端点)
判断左端点L的巧克力所对应的该种类的个数,若大于1,则左端点右移,区间内该种类巧克力数减少,将此时的LR区间保存。(确定左端点)
遍历剩余数组,将区间扩大,右端点逐步右移,每右移一个单位,记录区间内各种巧克力的数目,重复第二步骤确定下一个左端点,确定新的LR区间,与原LR区间比较长短,将答案更新为较短的LR区间。
最后遍历完整个数组即可找到最小区间LR。
#include<bits/stdc++.h> using namespace std; int a[1000000], b[2001];//a储存巧克力总数,b储存每种巧克力的个数 int main() { int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> a[i]; } int i = 1; int R = 0, L = 1; int sum = 0;//种类数 while (sum != m) { if (b[a[i]] == 0) sum++; b[a[i]]++; R++; i++; } while (b[a[L]] > 1) { b[a[L]]--; L++; } int ansL = L, ansR = R; while (i <= n) { b[a[i]]++; R++; i++; if(a[L]==a[R]) { L++; } if (ansR - ansL > R - L) { ansR = R; ansL = L; } } cout << ansL << " " << ansR; return 0; }
你是一个bilibili的六级号,由于经常一键三连,所以一个硬币都没有,现在你又做了个梦,在梦中你制定了一个硬币增加规则:
第一天登陆后硬币总数1个,第二天登陆后硬币总数112个,第三天登陆硬币总数112123个…,以此类推,梦中不知日月,你瞬间拥有了11212312341234512345612345671234567812345678912345678910123456789101112345678910…无穷多个硬币。
常年维护B站秩序的百漂怪看不下去了,决定随机挑一个数x,作为这个无穷数的第x位,如果你能正确答对这第x位上的数是什么,就赠送给你与这个数等量的硬币。
百漂怪总共会挑t次。
你决定编程模拟一下,搏一搏,单车变摩托。
第一行包含一个正整数t(1≤t≤10),表示百漂怪挑了t次。 接下来t行,每行一个正整数x (1 ≤ x≤ 2^31-1),表示第i次,百漂怪挑的是第x位。
输出共t行,每行输出对应第x位上的数。
2
3
8
2
2
6
222
66666
99999999
66656565
22222
2
6
4
9
4
1
1
记第一组为1,第二组为12,第三组为123,打表预处理计算除第2147482647位在第31268组,然后预处理计算前31268组的位数,存储在sum数组中,其中(int)log10((double)i)+1表示数据 i 的位数。然后模拟就行了,计算出当前要计算的第x位处在第k组中,然后找到所求位数位于整数 i 中,把 i 后面的数字除掉,取模之后即所求结果。
来源:POJ1019
#include<bits/stdc++.h> using namespace std; long int a[31270], b[31270]; void start() { int i; a[1] = 1; b[1] = 1; for (i = 2; i < 31270; i++) { a[i] = a[i - 1] + (int)log10((double)i) + 1; b[i] = b[i - 1] + a[i]; } } int res(int n) { int i = 1, j = 1, len = 0; for (i = 1; i < 31270; i++) { if (b[i] >= n) break; } int s = n - b[i - 1]; for (j = 1; len < s; j++) { len += (int)log10((double)j) + 1; } return ((j - 1) / (int)pow(10.0, len - s)) % 10; } int main() { start(); int t, x; cin >> t; while (t--) { cin >> x; cout << res(x) << endl; } return 0; }
你正在玩一个迷宫游戏,迷宫有n×n格,每一格有一个数字0或1,可以从某一格移动到相邻四格中的一格上。为了消磨时间,你改变了玩法,只许从0走到1或者从1走到0。
现在给你一个起点,请你计算从这个格子出发最多能移动多少个格子(包含自身)。
第1行包含两个正整数n和m(1≤n≤1000,1≤m≤10000)。
接下来n行,对应迷宫中的n行,每行n个字符,字符为0或者1,字符之间没有空格。
接下来m行,表示m次询问。每行2个正整数i,j,表示从迷宫中第i行第j列的格子开始走。
输出共m行,每行一个整数,分别对应于输入数据中的m次询问,给出最多能移动的格子数。
2 2
01
10
1 1
2 2
4
4
连接在一起的格子的答案是一样的,所以不需要多次搜索,DFS找连通块即可。
来源:洛谷P1141
#include<bits/stdc++.h> using namespace std; char maze[2000][2000];//记录迷宫 int flag[2000][2000];//判断该点是否走过 int n, m; int x, y; int ans[20000]; void dfs(int xx, int yy, int zz,int ii) { if (xx > 0 && yy > 0 && xx <= n && yy <= n && flag[xx][yy] == -1 && maze[xx][yy] - '0' == zz) { flag[xx][yy] = ii; ans[ii]++; dfs(xx + 1, yy, !zz, ii); dfs(xx - 1, yy, !zz, ii); dfs(xx, yy + 1, !zz, ii); dfs(xx, yy - 1, !zz, ii); } } int main() { memset(flag, -1, sizeof(flag)); memset(ans, 0, sizeof(ans)); cin >> n >> m; for (int i = 1; i <= n; i++) cin >> maze[i] + 1; for (int i = 0; i < m; i++) { cin >> x >> y; if (flag[x][y] == -1) { dfs(x, y, maze[x][y] - '0', i); } else { ans[i] = ans[flag[x][y]]; } } for (int i = 0; i < m; i++) { cout << ans[i] << endl; } }
给出n个圆盘的半径,现在要把这些圆盘依次放在柱子上,当准备把第i个半径为ai的圆盘放置到柱子上时,如果柱子顶部的圆盘半径小于ai,那么将柱子顶部的圆盘拿出,如果顶部的盘子半径仍然小于ai,那么继续拿出,直到顶部圆盘半径大于或等于ai为止,此时才把第i个盘子放到柱子上。那么,最后从下往上输出柱子上的圆盘半径依次是什么?
第一行包含一个整数n(n<=100000),表示有n个圆盘要依次放到柱子上。 接下来n行,每行一个整数,表示第i个圆盘的半径ai (ai<=100000)。
输出多行,表示最后柱子上中的圆盘半径。
5
5
3
2
4
1
5
4
1
模拟过程,先输入第一个盘子,而后依次输入盘子半径,若半径大于前一个的盘子,则将前一个盘子拿出,循环过程直到前一个盘子半径比该盘子大或前面没有盘子。
#include<bits/stdc++.h> using namespace std; int a[100050]; int main() { int n; cin >> n; cin >> a[0]; int i = 1, j = 1; int r; while (j < n) { cin >> r; while (r > a[i - 1] && i != 0) { a[i - 1] = 0; i--; } a[i] = r; i++; j++; } for (int i = 0; a[i] != 0; i++) { cout << a[i] << endl; } return 0; }
小明刚认识了新同学小红,他想要小红的微信号,小红不想直接告诉他,所以给了小明一串加密了的数字,并且把解密规则告诉了小明。
解密规则是:首先删除第1个数,接着把第2个数放在这串数的最后面,再删除第3个数,并把第4个数放在这串数的最后面……直至只剩最后一个数,把最后一个数也删除。
按照删除的顺序,把这些数字连在一起就是小红的微信号。请你按照解密规则帮小明得到小红的微信号。
第一行包括一个正整数n(1 < n < 500),表示这串微信号的长度;
第二行包括n个数字,即加密的小红的微信号。
输出解密后的微信号,相邻数字之间有空格。
9
1 2 3 4 5 6 7 8 9
1 3 5 7 9 4 8 6 2
设置头尾两个下标,将数组的第一个元素输出,头下标后移,将此时第一个元素放置末尾,尾下标后移,头下标后移,循环操作直到头尾下标重合。
#include<bits/stdc++.h> using namespace std; int a[500000], b[500000]; int main() { int n; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i]; } int head = 0, tail = n; while (head < tail) { cout << a[head]<<" "; head++; a[tail] = a[head]; tail++; head++; } return 0; }
学校里有n个孩子,从1到n对这些孩子进行编号。老师将给孩子们分发糖果,第i个孩子希望至少获得ai个糖果。
老师要求孩子们排队。 最初,第i个孩子站在队伍的第i个位置。 然后,老师开始分发糖果。分发糖果的规则是:将m个糖果给队伍中的第一个孩子,如果这个孩子没有得到足够的糖果,那么这个孩子会走到队伍的尽头;否则这个孩子就回家了。当队伍不为空时,重复这个规则一直分发糖果。 如果考虑所有孩子回家的顺序。老师想知道,哪个孩子将是这个顺序中的最后一个?
第一行包含两个整数n,m(1≤n≤100; 1≤m≤100)。 第二行包含n个整数a1,a2,…,an(1≤ai≤100)。
输出一个整数,代表最后一个孩子的编号。
3 3
2 4 3
2
建立结构体(包含:当前已有糖果数,所需糖果数,编号)
设置头尾下标,模拟题目操作即可。
#include<bits/stdc++.h> using namespace std; struct kid { int have = 0; int need; int index; }a[100000]; int main() { int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> a[i].need; a[i].index = i; } int head = 1, tail = n + 1; while (1) { a[head].have += m; if (a[head].have >= a[head].need) { head++; } else { a[tail].have = a[head].have; a[tail].need = a[head].need; a[tail].index = a[head].index; tail++; head++; } if (tail - head == 1) { cout << a[head].index << endl; break; } } return 0; }
给定一个含有n个整数的数列a1,a2,…an。定义函数 f(ai)表示数列中第i个元素ai之后第一个大于ai的元素的下标,若这样的元素不存在,则f(ai)=0。
第一行包含一个正整数n(n<=1e6);
第二行包含n个正整数 a1,a2,…an(1<=ai<=1e9)。
输出仅一行包含 n个整数,分别代表 f(ai) 的值。
5
1 4 2 3 5
2 5 4 5 0
双重循环,遍历数组,找到比当前元素大的第一个下标输出,若未找到,则输出0。
#include<bits/stdc++.h> using namespace std; int a[1000050]; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } int i = 1, j; for (i = 1; i <= n; i++) { for (j = i + 1; j <= n; j++) { if (a[j] > a[i]) { cout << j << " "; break; } if (j == n) { cout << 0 << " "; } } if (i == n) { cout << 0 <<" "; } } return 0; }
所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右进行(不用考虑运算符的优先级)。
如:中缀表达式 3*(5–2)+7 对应的后缀表达式为:352-*7+ 。
请将给出的中缀表达式转化为后缀表达式并输出。
输入仅一行为中缀表达式,式中所有数字均为个位数,表达式长度小于1000。
输出一行,为后缀表达式,式中无空格。
2+4×8+(8×8+1)/3
248×+88×1+3/+
设置优先级,将操作数直接输出,操作符判断优先级后再输出,括号需要特别判断。
#include<bits/stdc++.h> using namespace std; stack<char>q; int level(char x) { int ll; if (x == '*' || x == '/') ll = 2; if (x == '+' || x == '-') ll = 1; return ll; } //判断优先级 int main() { int i; char s[1000]; memset(s, '\0', sizeof(s)); cin >> s; int l = strlen(s); for (i = 0; i < l; i++) { if (s[i] >= '0' && s[i] <= '9') cout << s[i]; //如果是操作数直接输出操作数 if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') { while (1) { if (q.empty() || q.top() == '(') { q.push(s[i]); break; }//空栈或为括号内的直接入栈; else if (level(s[i]) > level(q.top())) { q.push(s[i]); break; }//当前运算符优先级大于栈顶则入栈 else { cout << q.top(); q.pop(); }//优先级小于栈顶则弹出栈顶 } } if (s[i] == '(') { q.push(s[i]); }//左括号压入 if (s[i] == ')') { //遇到右括号 while (q.top() != '(') { cout << q.top(); q.pop(); } //将除左括号以外的操作符全部输出 q.pop(); //弹出左括号 } if (i == l - 1) { //数据到底了,输出栈中剩余所有操作符 while (!q.empty()) { cout << q.top(); q.pop(); } } } return 0; }
Kunkun学长觉得应该让学弟学妹了解一下这个知识点:后缀表达式相对于中缀表达式更容易让计算机理解和学习。现在kunkun学长给出一串后缀表达式,你能帮他算出这个后缀表达式的值吗?
第一行输入后缀表达式长度n(1<=n<=25000);
第二行输入一个字符串表示后缀表达式(每个数据或者符号之间用逗号隔开,保证输入的后缀表达式合法,每个数包括中间结果保证不超过long long长整型范围)
输出一个整数,即后缀表达式的值。
6
10,2,+
12
14
2,10,2,+,6,/,-
遇到操作数,存入数组,注意多位数;遇到操作符,将数组中的最后两个数进行运算,两个操作数弹出,将结果存入数组。
循环操作,数组中最后一个数即为答案。
#include<bits/stdc++.h> using namespace std; long long int a[2000000]; char op[1000000]; int main() { long long int n, k = 0; long long int num = 0; cin >> n; for (long long int i = 0; i < n; i++) { cin >> op[i]; } for (long long int i = 0; i < n; i++) { if (op[i] >= '0' && op[i] <= '9') { if (op[i - 1] == '-') { num = num * 10 + (op[i] - '0'); num = -num; } else { if (num < 0) { num = num * 10 - (op[i] - '0'); } else { num = num * 10 + (op[i] - '0'); } } } else if (op[i] == ',') { if (num != 0) { a[k] = num; num = 0; k++; } } else if (op[i] == '+') { a[k - 2] = a[k - 2] + a[k - 1]; a[k - 1] = 0; k--; } else if (op[i] == '-') { if (op[i + 1] == ',' || i == n - 1) { a[k - 2] = a[k - 2] - a[k - 1]; a[k - 1] = 0; k--; } } else if (op[i] == '*') { a[k - 2] = a[k - 2] * a[k - 1]; a[k - 1] = 0; k--; } else if (op[i] == '/') { a[k - 2] = a[k - 2] / a[k - 1]; a[k - 1] = 0; k--; } } cout << a[k - 1]; return 0; }
给出一串包含 ( 、 ) 、[ 和 ] 的字符串,字符串在以下三种情况下为合法的:
1)字符串为空;
2)如果A和B都是合法的,那么AB也是合法的;
3)如果A是合法的,那么(A)和[A]也是合法的。
试判断输入的字符串是否合法。
输入包括一串由若干个 ( 、 ) 、 [ 或 ] 组成的字符串,字符串长度不超过100。
如果该字符串合法,输出“Yes”;否则输出“No”。
([])
Yes
遇到左括号直接入栈,遇到右括号判断与栈顶是否匹配,若匹配则弹出栈顶,若不匹配则输出No,结束。
#include<bits/stdc++.h> using namespace std; char a[1000]; stack<char>q; int main() { memset(a, '\0', sizeof(a)); cin >> a; int l = strlen(a); for (int i = 0; i < l; i++) { if (a[i] == '(' || a[i] == '[') q.push(a[i]); if (a[i] == ')') { if (q.empty() == true) { cout << "No"; return 0; } else { if (q.top() == '(') q.pop(); else { cout << "No"; return 0; } } } if (a[i] == ']') { if (q.empty() == true) { cout << "No"; return 0; } else { if (q.top() == '[') q.pop(); else { cout << "No"; return 0; } } } } cout << "Yes"; return 0; }
已知公交车中有n排座位,每排都有2个座位。第i排的两个座位的宽度均为wi厘米。没有相同宽度的两排座位。
公共汽车最初是空的。有2n位乘客按顺序先后进入公共汽车。 乘客分为两种类型:
内向者:总是选择两个座位都没人的一排。在这些排中,他选择座位宽度最小的,并占据了其中的一个座位; 外向型:总是选择有人的一排。 在这些排中,他选择座位宽度最大的那个,并占据了空位。
你会得到每排座位的宽度和乘客进入公共汽车的顺序。 请你帮忙确定每位乘客将乘坐哪一排座位。
第一行包含一个整数n(1 ≤ n ≤ 200),表示公共汽车上座位的总排数。
第二行是一个包含n个整数的序列w 1,w 2,…,w n(1 ≤ w i ≤ 10000),其中wi是第i行中每个座位的宽度。 保证所有 w i 都不同。
第三行包含一个长度为 2n 的字符串,由数字“0”和“1”组成,该字符串描述了乘客进入公共汽车的顺序。 如果第j个字符是 ‘0’,那么说明第 j 个进入公共汽车的乘客是内向型的;如果第j个字符是 ‘1’,则表示第j个进入公交车的乘客是外向型的。 保证外向者的数量等于内向者的数量(即’0’和’1’的个数均为 n),并且对于每个外向者总是有合适的行。
打印 2n 个整数,整数之间以空格分隔,表示乘客将坐的排。 乘客的顺序应与输入的顺序相同。
2
3 1
0011
2 1 1 2
6
10 8 9 11 13 5
010010011101
6 6 2 3 3 1 4 4 1 2 5 5
#include<bits/stdc++.h> using namespace std; char s[500]; struct seat { int w;//座位宽度 int p;//排 }a[250]; stack<int>q; int cmp(seat a, seat b) { return a.w < b.w; } int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i].w; a[i].p = i; } sort(a + 1, a + n + 1, cmp); cin >> s; int k = 1; for (int i = 0; i < 2 * n; i++) { if (s[i] == '0') { cout << a[k].p << " "; q.push(a[k].p); k++; } if (s[i] == '1') { cout << q.top() << " "; q.pop(); } } return 0; }
如果通过插入“ +”和“ 1”可以从中得到格式正确的数学表达式,则将带括号的序列称为正确的。
例如,序列 “(())()”,"()“和 “(()(()))“是正确的,而”)(”,”(()))(“和”(()" 不是。
定义重新排序操作:选择括号序列的任意连续子段(子字符串),然后以任意方式对其中的所有字符进行重新排序。
当重新排序的子段的长度为t时,重新排序操作需要耗时t秒。
例如,对于“))((”,他可以选择子字符串“)(”并重新排序“)()(”(此操作将花费2秒)。
不难看出,重新排序操作不会改变左括号和右括号的数量。
现在,LD想花费最少的时间,通过任意次数(可能为零)执行重新排序操作来使括号序列变成正确的。
第一行包含一个整数n(1≤n≤1e6),表示序列的长度;
第二行包含一个长度为n的字符串,仅由字符‘(’和‘)’组成。
输出一个整数,表示使括号序列正确的最小秒数;如果不可能实现,则输出-1。
8
))((())(
6
遍历字符串,若栈为空,遇到左括号直接压入;遇到右括号则秒数+1,再压入。若栈非空,遇到左括号判断栈顶是否为右括号,若是则需要重新排列,秒数+1,若否则直接压入;遇到右括号,判断栈顶是否为左括号,若是则匹配,弹出栈顶,若否则需要重新排列,秒数+1,压入。
#include<bits/stdc++.h> using namespace std; int n, ans = 0; char s[1000050]; stack<char>q; int main(){ cin >> n; cin >> s; for (int i = 0; i < n; i++) { if (q.empty()) { if(s[i]=='(') q.push(s[i]); else { q.push(s[i]); ans++; } } else { if (s[i] == '(') { if (q.top() == ')') { ans++; q.pop(); } else { q.push(s[i]); } } if (s[i] == ')') { if (q.top() == '(') { q.pop(); } else { q.push(s[i]); ans++; } } } } cout << ans; return 0; }
有N堆石子,每堆石子有若干石头,所有石头的总数是N的倍数。
可以在任意一堆上取若干石头,进行移动。移动规则是:在第一堆上取的石子,只能移到第二堆;在第N堆上取的石子,只能移到N-1堆;其他堆上取的,可以移到相邻左边或者右边。如何用最少的移动次数使得每堆石子的数量一样多呢?
当N=4时,4堆石子数为:9、8、17、6
移动3次可以使4堆数目一样多:
从第3堆取4个石子放到第4堆(9、8、13、10)
从第3堆取3个放到第2堆(9、11、10、10)
从第2堆取1个放到第1堆(10、10、10、10)
第一行包含一个整数N(1<= N <=100),表示有N堆石子;
接着有N行,每行一个整数ai(1<= ai <=10000),表示第i堆石子的数量。
输出一个整数,表示使所有石子堆的石子均达到相等时需要的最少移动次数。
4
9 8 17 6
3
洛谷P1031
#include<bits/stdc++.h> using namespace std; int main() { int a[200]; int n, avg = 0, ans = 0; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i]; avg += a[i]; } avg /= n; for (int i = 1; i < n; i++) { if (a[i-1] != avg) { a[i] += a[i - 1] - avg; ans++; } } cout << ans; return 0; }
你已经两个月没有出门了,无聊到自己和自己玩“一键三连”的游戏。这个游戏很简单,你制作了规格为4×4的棋盘,一开始棋盘中所有格子都是空的,全为‘.’,紧接着你一人分饰两角,一个画‘x’填到一个为空的格子里,另一个画‘o’填到另一个为空的格子,这个过程交替进行。如果一方先使横的、竖的或斜的有连续的三个格子都是属于自己的标记,那么就赢了。
你刚刚看完一个视频,现在准备开始玩“一键三连”,于是你拿出了很久之前的棋盘,它可能下过,也可能没有(即全部填‘.’),但保证此时没有达到画‘o’的胜局。你选择在一个为空的格子里画‘x’后马上停止,看看是否能构成画‘x’的胜局。
输入共四行四列,表示由“.”(表示空的),“x”(小写字母x)或“o”(小写字母o)组成棋盘。
如果你一键三连了,输出“YES”,否则输出“NO”。
xx…
.oo.
x…
oox.
YES
x.ox
ox…
x.o.
oo.x
NO
遍历二维数组,暴力判断。
#include<bits/stdc++.h> using namespace std; char mp[10][10]; int judge() { for (int i = 1; i <= 4; i++) { for (int j = 1; j <= 4; j++) { if (mp[i][j] == 'x' && mp[i][j + 1] == 'x' && mp[i][j + 2] == 'x' && j + 2 <= 4) { return 1; } } } for (int i = 1; i <= 4; i++) { for (int j = 1; j <= 4; j++) { if (mp[i][j] == 'x' && mp[i + 1][j] == 'x' && mp[i + 2][j] == 'x' && i + 2 <= 4) { return 1; } } } for (int i = 1; i <= 4; i++) { for (int j = 1; j <= 4; j++) { if (mp[i][j] == 'x' && mp[i + 1][j + 1] == 'x' && mp[i + 2][j + 2] == 'x' && i + 2 <= 4 && j + 2 <= 4) { return 1; } } } for (int i = 1; i <= 4; i++) { for (int j = 1; j <= 4; j++) { if (mp[i][j] == 'x' && mp[i + 1][j - 1] == 'x' && mp[i + 2][j - 2] == 'x' && i + 2 <= 4 && j - 2 >= 1) { return 1; } } } return 0; } int main() { for (int i = 1; i <= 4; i++) { for (int j = 1; j <= 4; j++) { cin >> mp[i][j]; } } for (int i = 1; i <= 4; i++) { for (int j = 1; j <= 4; j++) { if (mp[i][j] == '.') { mp[i][j] = 'x'; if (judge()) { cout << "YES"; return 0; } mp[i][j] = '.'; } } } cout << "NO"; return 0; }
给你一罐颜料,并规定写出1-9每个数字所用的颜料是指定量的,当你用这罐颜料写下的数字越大,你得到的积分越多。
那么,你能得到的最大积分是多少呢?
第一行包含一个整数n(0≤n≤1000),表示给定颜料量。
第二行包含九个正整数a1,a2,… ,a9,分别表示写下数字1-9所需要的颜料量。
输出一个数,表示你能得到的最大积分;如果颜料连一个数字都不够写,那么输出-1。
2
9 11 1 12 5 8 9 10 6
33
贪心,先找出最大位数,再从最高位开始,找每一位上的最大数字。
#include<bits/stdc++.h> using namespace std; int main() { int n, a[10], min; cin >> n; for (int i = 1; i < 10; i++) { cin >> a[i]; if (i == 1) { min = a[1]; } else { if (a[i] <= min) { min = a[i]; } } } if (n < min) { cout << "-1"; return 0; } else { int w = n / min;//最大能写的位数 for (int i = w; i > 0; i--) { for (int j = 9; j >= 1; j--) { if (n >= a[j] && (n - a[j]) / min >= i - 1) { cout << j; n -= a[j]; break; }//从9开始,若能将当前位数的最高位替代,则用该数字替代,保证最大 } } } return 0; }
汉堡包在大街上大摇大摆的走着,看着手机上一道难倒数万人的小学数学题:
1 + 1 = 0
1 + 6 = 1
6 + 6 = 2
8 + 1 = 2
8 + 6 = 3
汉堡包看完之后发现上面这些加法的答案就是看1,6,8中圈圈的个数嘛!
突然之间,所有大厦上的LED屏幕上的广告全部变成数字1,6,8三个数字的随机闪现。
现给你一块n*m的LED屏幕,上面有且仅有一个数字(1,6,or 8),请你输出你看见的那个字母。
第一行输入两个整数n,m(2<= m, n <= 1000);
接下来n行,每行由m个数字0和1组成,其中1表示数字1,6,8的组成部分。
输出一个整数,代表图形表示的数字。
7 7
0 0 0 0 0 0 0
0 0 1 1 1 0 0
0 0 1 0 1 0 0
0 0 1 1 1 0 0
0 0 1 0 1 0 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
8
从最后一行遍历至第一行,
若构成数字为1,每行1的个数都相同;
若构成数字为6,每行1的个数会出现两次减少;
若构成数字为8,每行1的个数会出现一次减少。
#include<bits/stdc++.h> using namespace std; int a[1000][1000]; int b[1000] = { 0 };//记录每行1的个数 int c[1000]; int main() { int n, m, i, j, count = 0, min; cin >> n >> m; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { cin >> a[i][j]; } } for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { if (a[i][j] == 1) b[i]++; } } for (i = 0, j = 0; i < n; i++) { if (b[i] != 0) c[j++] = b[i]; } min = c[j - 1]; for (i = j - 2; i >= 0; i--) { if (c[i] < min) { min = c[i]; count++; } } if (count == 0) cout << "1"; if (count == 1) cout << "8"; if (count == 2) cout << "6"; return 0; }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。