1/1 + 1/2 + 1/3 + 1/4 + ... 在数学上称为调和级数。
它是发散的,也就是说,只要加上足够多的项,就可以得到任意大的数字。
但是,它发散的很慢:
前1项和达到 1.0
前4项和才超过 2.0
前83项的和才超过 5.0
那么,请你计算一下,要加多少项,才能使得和达到或超过 15.0 呢?
请填写这个整数。
注意:只需要填写一个整数,不要填写任何多余的内容。比如说明文字。
#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
double eps = 1e-14;
using namespace std;
char s[10010];
int main() {
double tmp = 0.0;
int i = 1;
while (true) {
tmp += 1.0 / i;
if (tmp - 15.0 >= eps) {
cout << i;
return 0;
}
i++;
}
return 0;
}
注意:eps要设置的足够小才可以,要不然,会报错
Give you many positive integer N (N<=23), for each N, just output N*(N+1)/2 integers in a single line, separated by space. (Don't ask me why.) For each N, the output line contains integers from 1 to N, and each just once. Again, do not ask me why, thank you. I'm so busy. But I can tell you a secret, the output has relationship with number triangle. As:(N=3)
1
2 6
3 4 5
See the sample for more information.
【输入形式】
a positive integer N (N<=23).
【输出形式】
For each N, output N*(N+1)/2 integers in a single line, separated by a blank space.
【样例输入】
3 4 2 6
【样例输出】
1 2 6 3 4 5 1 2 9 3 10 8 4 5 6 7 1 2 3 1 2 15 3 16 14 4 17 21 13 5 18 19 20 12 6 7 8 9 10 11
#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
using namespace std;
int main() {
int n, y, x;
while (scanf("%d", &n) != EOF) {
int a[23][23] = { 0 }, m = 1;
for (y = n; y >= 1; y--) {
a[1][y] = m++;
}
for (x = 2; x <= n; x++) {
a[x][1] = m++;
}
x = x - 1;
y = y + 1;
while (m <= (n * (n + 1) / 2)) {
for (; x >= 1 && y <= n;) {
if (a[--x][++y] == 0) {
a[x][y] = m++;
}
else {
break;
}
}
if (m > n * (n + 1) / 2) break;
//下面的步骤是因为虽然break,x和y还是多加了一次,要注意。
x = ++x;
y = y - 1;
//
for (; y >= 1;) { //for里面第一个数可以没有,不用其他的数字表示了。
if (a[x][--y] == 0) {
a[x][y] = m;
m++;
}
else {
break;
}
}
if (m > n * (n + 1) / 2) break;
y = y + 1;
for (; x <= n;) {
if (a[++x][y] == 0) {
a[x][y] = m++;
}
else {
break;
}
}
if (m > n * (n + 1) / 2) break;
x = x - 1;
}
for (y = n; y >= 1; y--) {
for (x = 1; x <= n - y + 1; x++) {
if (y == 1 && x == n)
printf("%d\n", a[x][y]);
else
printf("%d ", a[x][y]);
}
}
}
return 0;
}
有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
【输入形式】
第一行为一个整数,表示箱子容量;
第二行为一个整数,表示有n个物品;
接下来n行,每行一个整数表示这n个物品的各自体积。
【输出形式】
一个整数,表示箱子剩余空间。
【样例输入】
24 6 8 3 12 7 9 7
【样例输出】
0
线性动态规划
#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
using namespace std;
int a[31]; //存放物品的体积
int dp[20001] = { 0 }; //dp[i]表示箱子容积为i时可放入的物品的体积 ,注意要初始化为0
int main()
{
int i, j;
int t;
int V;//箱子体积
int n;//个数
cin >> V;
cin >> n;
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
for (i = 0; i < n; i++)//外循环,遍历每个箱子
{
for (j = V; j >= a[i]; j--)//遍历每个容积
{
if (dp[j] > (dp[j - a[i]] + a[i]))
dp[j] = dp[j];
else
dp[j] = dp[j - a[i]] + a[i]; //取max,最优解
}
}
printf("%d", V - dp[V]); //输出最小的容积
return 0;
}
牛顿问题,因由牛顿题出而得名,也有人称这一类问题叫做牛吃草问题。英国著名的物理学家牛顿曾编过这样一道数学题:牧场上有一片青草,每天都生长得一样快。这片青草供给10头牛吃,可以吃22天,或者供给16头牛吃,可以吃10天,如果供给25头牛吃,可以吃几天?
【输入形式】
此题没有输入
【输出形式】
请用printf()语句输出正确答案。
假设你所求得的最后结果是1000,则应该printf("1000");
为了便于判断正误,请不要输出多余的字符,如空格,句号。
比赛选手可以多次提交答案,我们将以最后一次提交的结果作为最后成绩。
【样例输出】
1000
答案 5.5
形如:1/a 的分数称为单位分数。
可以把1分解为若干个互不相同的单位分数之和。
例如:
1 = 1/2 + 1/3 + 1/9 + 1/18
1 = 1/2 + 1/3 + 1/10 + 1/15
1 = 1/3 + 1/5 + 1/7 + 1/9 + 1/11 + 1/15 + 1/35 + 1/45 + 1/231
等等,类似这样的分解无穷无尽。
我们增加一个约束条件:最大的分母必须不超过30
请你求出分解为n项时的所有不同分解法。
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 2000ms
【输入形式】
输入一个整数n,表示要分解为n项(n<12)
【输出形式】
输出分解后的单位分数项,中间用一个空格分开。
每种分解法占用一行,行间的顺序按照分母从小到大排序。
【样例输入】
4
【样例输出】
1/2 1/3 1/8 1/24
1/2 1/3 1/9 1/18
1/2 1/3 1/10 1/15
1/2 1/4 1/5 1/20
1/2 1/4 1/6 1/12
#include <iostream>
using namespace std;
void f(int A[], int n, int qishi, int jishu) {
if (jishu == n) {
int num1 = 1, num2 = 0;
for (int i = 0; i < n; i++) {
num1 *= A[i];
}
for (int j = 0; j < n; j++) {
num2 += num1 / A[j];
}
if (num1 == num2) {
for (int i = 0; i < n; i++) {
cout << "1/" << A[i] << " ";
}
cout << endl;
}
}
else {
for (int i = qishi; i < 30; i++) {
A[jishu] = i;
f(A, n, i + 1, jishu + 1);
}
}
}
int main() {
int n, A[30];
cin >> n;
f(A, n, 2, 0);
return 0;
}
4/7,错了3个样例,代码是错的
Hanks 博士是BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫Hankson。现 在,刚刚放学回家的Hankson 正在思考一个有趣的问题。 今天在课堂上,老师讲解了如何求两个正整数c1 和c2 的最大公约数和最小公倍数。现 在Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公 倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0,a1,b0,b1,设某未知正整 数x 满足: 1. x 和a0 的最大公约数是a1; 2. x 和b0 的最小公倍数是b1。 Hankson 的“逆问题”就是求出满足条件的正整数x。但稍加思索之后,他发现这样的 x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的x 的个数。请你帮 助他编程求解这个问题。
【输入形式】
输入第一行为一个正整数n,表示有n 组输入数据。
接下来的n 行每 行一组输入数据,为四个正整数a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入 数据保证a0 能被a1 整除,b1 能被b0 整除。
数据规模和约定
对于 50%的数据,保证有1≤a0,a1,b0,b1≤10000 且n≤100。
对于 100%的数据,保证有1≤a0,a1,b0,b1≤2,000,000,000 且n≤2000。
【输出形式】
输出共n 行。每组输入数据的输出结果占一行,为一个整数。
对于每组数据:若不存在这样的 x,请输出0; 若存在这样的 x,请输出满足条件的x 的个数;
【样例输入】
2 41 1 96 288 95 1 37 1776
【样例输出】
6 2
【提示】
样例说明
第一组输入数据,x 可以是9、18、36、72、144、288,共有6 个。
第二组输入数据,x 可以是48、1776,共有2 个。
下面的代码是直接复制的
#include<stdio.h>
int gcd(int a, int b)//辗转相除法求最大公约数
{
int t;
if (a < b)//大数放a中,小数放b中
{
t = a;
a = b;
b = t;
}
while (b != 0 && a % b != 0)//余数不为0,继续相除,直到余数为0
{
t = a % b;
a = b;
b = t;
}
return b;//返回最大公约数到调用函数处
}
void jisuan(int a0, int a1, int b0, int b1, int* sum)
{
int i, x;
for (i = 1; i * i <= b1; i++)
{
if (b1 % i == 0)
{
if (i % a1 == 0)
if (gcd(b1 / b0, b1 / i) == 1 && gcd(a0 / a1, i / a1) == 1)
{
++* sum; //满足条件的数据的个数
}
int j = b1 / i;
if (j % a1 != 0 || i == j)
{
continue;
}
if (gcd(b1 / b0, b1 / j) == 1 && gcd(a0 / a1, j / a1) == 1)
{
++* sum;
}
}
}
}
int main()
{
int n;
scanf("%d\n", &n);//输入一个正整数(表示输入数据的组数)
while (n--)
{
int a0, a1, b0, b1;
int sum = 0;
scanf("%d %d %d %d", &a0, &a1, &b0, &b1); //输入四个正整数
if (b1 % a1 == 0)
{
jisuan(a0, a1, b0, b1, &sum);
}
printf("%d\n", sum);
}
return 0;
}
gcd(x,a0) = a1,lcm(x,b0) = b1
即gcd(x,a0) = a1,x*b0 = b1*gcd(x,b0)
又a1 = gcd(x,a0)<=x,gcd(x,b0)<=b0,x*b0 = b1*gcd(x,b0)<=b1*b0,
所以,x<=b1且x>=a1
在[a1,b1]之间枚举x
//#include<bit/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <cstring>//memset
#include <string>
using namespace std;
const int maxn = 1e5 + 100;
bool IsPrime(int m) {
if (m == 2)
return true;
int tmp = sqrt(m);
for (int i = 2; i <= tmp; i++)
if (m % i == 0)
return false;
return true;
}
int gcd_wx(int a, int b) {
while (a != b)
{
if (a > b)
a = a - b;
else
b = b - a;
}
return a;
}
bool leapYear(int y) {
if (y % 400 == 0)
return true;
if (y % 4 == 0 && y % 100 != 0)
return true;
return false;
}
int qushu(int m){
while(m){
int tmp = m%10;
m/=10;
}
return 0;
}
int dx[4] = { 1,0,0,-1 };
int dy[4] = { 0,-1,1,0 };
char dire[4] = { 'D','L','R','U' };
struct Road{
int d;
int cost;
Road ():d(0),cost(0){
}
Road(int dd,int c):d(dd),cost(c){
}
};
bool cmp(int a,int b){
return a>b;
}
int n;
int a0,a1,b0,b1;
int main() {
cin>>n;
for(int times = 1;times <= n;times++)
{
int ans = 0;
cin>>a0>>a1>>b0>>b1;
for(int i = a1;i<= b1;i++){
if(gcd_wx(i,a0) == a1&&gcd_wx(i,b0)*b1 == i*b0)
ans++;
}
cout<<ans<<endl;
}
return 0;
}
A 村的元宵节灯会上有一迷题:
请猜谜 * 请猜谜 = 请边赏灯边猜
小明想,一定是每个汉字代表一个数字,不同的汉字代表不同的数字。
请你用计算机按小明的思路算一下,然后提交“请猜谜”三个字所代表的整数即可。
请严格按照格式,通过浏览器提交答案。
注意:只提交一个3位的整数,不要写其它附加内容,比如:说明性的文字。
在C/C++语言中,整型所能表示的范围一般为-231到231(大约21亿),即使long long型,一般也只能表示到-263到263。要想计算更加规模的数,就要用软件来扩展了,比如用数组或字符串来模拟更多规模的数及共运算。
现在输入两个整数,请输出它们的乘积。
数据规模和约定
每个整数不超过10000位
输入
两行,每行一个正整数,每个整数不超过10000位
输出
一行,两个整数的乘积。
样例输入
99 101
样例输出
9999
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
using namespace std;
string x, y;
int a[100005], b[100005], c[100005], la, lb, lc;
int main() {
cin >> x >> y;
la = x.length();
lb = y.length();
for (int i = 0; i < la; i++) {
a[la - i] = x[i] - '0';
}
for (int i = 0; i < lb; i++) {
b[lb - i] = y[i] - '0';
}
for (int i = 1; i <= la; i++) {
for (int j = 1; j <= lb; j++) {
c[i + j - 1] += a[i] * b[j];
c[i + j] += c[i + j - 1] / 10;
c[i + j - 1] %= 10;
}
}
lc = la + lb;
while (c[lc] == 0 )lc--;
for (int i = lc; i >= 1; i--)
cout << c[i];
return 0;
}
看下面的算式:
□□ x □□ = □□ x □□□
它表示:两个两位数相乘等于一个两位数乘以一个三位数。
如果没有限定条件,这样的例子很多。
但目前的限定是:这9个方块,表示1~9的9个数字,不包含0。
该算式中1至9的每个数字出现且只出现一次!
比如:
46 x 79 = 23 x 158
54 x 69 = 27 x 138
54 x 93 = 27 x 186
.....
请编程,输出所有可能的情况!
注意:左边的两个乘数交换算同一方案,不要重复输出!
(乘号用英文字母x代替,符号与数字之间有一个空格)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
using namespace std;
int main()
{
int a[9] = { 1,2,3,4,5,6,7,8,9 };
do {
int t1, t2, t3, t4;
t1 = a[0] * 10 + a[1];
t2 = a[2] * 10 + a[3];
t3 = a[4] * 10 + a[5];
t4 = a[6] * 100 + a[7] * 10 + a[8];
if (t1 < t2 && t1 * t2 == t3 * t4) {
cout << t1 << " x " << t2 << " = " << t3 << " x " << t4 << endl;
}
} while (next_permutation(a, a + 9));
return 0;
}
C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了m座大桥,每座大桥连接两座小岛。两个小岛间可能存在多座桥连接。然而,由于海水冲刷,有一些大桥面临着不能使用的危险。
如果两个小岛间的所有大桥都不能使用,则这两座小岛就不能直接到达了。然而,只要这两座小岛的居民能通过其他的桥或者其他的小岛互相到达,他们就会安然无事。但是,如果前一天两个小岛之间还有方法可以到达,后一天却不能到达了,居民们就会一起抗议。
现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。现在他想知道居民们会有多少天进行抗议。
样例说明
第一天后2和3之间的桥不能使用,不影响。
第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。
第三天后3和4之间的桥不能使用,居民们会抗议。
数据规模和约定
对于30%的数据,1<=n<=20,1<=m<=100;
对于50%的数据,1<=n<=500,1<=m<=10000;
对于100%的数据,1<=n<=10000,1<=m<=100000,1<=a, b<=n, 1<=t<=100000。
输入
输入的第一行包含两个整数n, m,分别表示小岛的个数和桥的数量。
接下来m行,每行三个整数a, b, t,分别表示该座桥连接a号和b号两个小岛,能使用t天。小岛的编号从1开始递增。
输出
输出一个整数,表示居民们会抗议的天数。
样例输入
4 4 1 2 2 1 3 2 2 3 1 3 4 3
样例输出
2
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
using namespace std;
struct node
{
int x, y, d;
} s[100000 + 5];
int n, fa[10000 + 5];
bool cmp(node a, node b)
{
return a.d > b.d;
}
void Set()
{
for (int i = 1; i <= n; i++)
fa[i] = i;
}
int find(int x) {
if (fa[x] == x)
return x;
int root = x;//返回的祖先节点
while (fa[root] != root)root = fa[root];//不断回溯
int tmp = x;//临时存储x
//路径压缩
while (fa[x] != x) {
tmp = fa[x];//存储上一个节点fa[x]
fa[x] = root;//将本节点x指向根节点
x = tmp;//更新x
}
return root;
}
bool Union(int x, int y)
{
x = find(x);
y = find(y);
if (x != y)
{
fa[x] = y;
return 1;
}
return 0;
}
int main()
{
int m;
while (~scanf("%d%d", &n, &m))
{
for (int i = 1; i <= m; i++)
{
scanf("%d%d%d", &s[i].x, &s[i].y, &s[i].d);
}
sort(s + 1, s + m + 1, cmp);
Set();
int pre = -1, ans = 0;//表示前一次是在第几天进行反抗的
for (int i = 1; i <= m; i++)
{
int way = Union(s[i].x, s[i].y);//way=0表示之前有桥,不需要在建桥
if (way == 1 && s[i].d != pre)
{
ans++;
pre = s[i].d;
}
}
cout << ans << endl;
}
return 0;
}
给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。
输入
输入的第一行为一个整数n,表示棋盘的大小。
接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
输出
输出一个整数,表示总共有多少种放法。
样例输入
4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
样例输出
2
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
using namespace std;
#include <iostream>
#include<math.h>
using namespace std;
int n;
int map[9][9];
int bq[9], wq[9];
//定义bq,wq分别用于存储 在每一行都在哪一个位置摆放了黑(black queen),白皇后 (write queen)
int sum = 0;
bool Ispos(int cur, int* q)//判断皇后是否满足条件
{
for (int i = 1; i < cur; i++)
{
if (q[i] == q[cur] || (abs(i - cur) == abs(q[i] - q[cur])))
return false;
//若有一个满足上面的条件的,就会返回false
}
return true;
}
void WQ(int cur)
{
if (cur == n + 1)//白皇后也全部放置,次数+1
{
sum++;
}
for (int i = 1; i <= n; i++)
{
if (bq[cur] == i)continue;//判断是否黑皇后已摆放的位置
if (map[cur][i] == 0)continue;
wq[cur] = i;
if (Ispos(cur, wq))
{
WQ(cur + 1);
}
}
}
void BQ(int cur)
{
if (cur == n + 1) //若黑皇后放置完,再处理白皇后
{
WQ(1);
}
for (int i = 1; i <= n; i++)
{
if (map[cur][i] == 0)continue;//若map对应的位置为0,即不能放置皇后 ,跳过这次循环
bq[cur] = i;
if (Ispos(cur, bq))
{
BQ(cur + 1);
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)// i = 1为了与一般认识一样
{
for (int j = 1; j <= n; j++)// j = 1为了与一般认识一样
{
cin >> map[i][j];
}
}
BQ(1);//执行摆放黑皇后函数(当然先摆放白皇后也行,不过要改一些),
//里面是1,表示从第1列开始,放置
cout << sum;
return 0;
}