HDUOJ 2040-2059
2040 亲和数
关键在于约数的寻找,和求素数的方法一样,循环2<=i<=N/2做模运算。
#include<iostream>
#include <stdio.h>
using namespace std;
int qinhe(int a) {
int sum = 0;
for (int i = 1; i <= a / 2; i++) {
if (a%i == 0)
sum += i;
}
return sum;
}
int main() {
int a, b;
int n;
cin >> n;
while (n--) {
cin >> a >> b;
if (qinhe(a) == b && qinhe(b) == a)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
2041 超级楼梯 (递推、斐波那契数列)
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
//递归太慢了
int step(int m) {
if (m == 1) return 1;
else if (m == 2) return 1;
else if (m >= 3)
return step(m - 1) + step(m - 2);
}
int main() {
int n, m;
//到达每层楼梯的走法
int a[41];
cin >> n;
while (n--) {
cin >> m;
a[1] = 1;
a[2] = 1;
for (int i = 3; i <= 40; i++) {
a[i] = a[i - 1] + a[i - 2];
}
cout << a[m] << endl;
}
}
2042 不容易系列之二(2013)
int main() {
int n, a,sum;
cin >> n;
while (n--) {
cin >> a;
sum = 3;
while(a--)
sum = (sum - 1) * 2;
cout << sum << endl;
}
}
2043 密码
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
int main() {
int m;
char str[50];
cin >> m;
getchar();
while (m--) {
gets_s(str);
int len = strlen(str);
if (len < 8 || len>16) {
cout << "NO" << endl;
continue;
}
int a[4] = { 0 };
for (int i = 0; i < len; i++) {
if (str[i] >= 'a'&&str[i] <= 'z')
a[0]=1;
else if (str[i] >= 'A'&&str[i] <= 'Z')
a[1]=1;
else if (str[i] >= '0'&&str[i] <= '9')
a[2]=1;
else if (str[i] == '~' || str[i] == '!' || str[i] == '@' || str[i] == '#' || str[i] == '$' || str[i] == '%' || str[i] == '^')
a[3]=1;
}
if (a[0] + a[1] + a[2] + a[3]>=3) {
cout << "YES" << endl;
}
else cout << "NO" << endl;
}
}
2044 一只小蜜蜂…(递推、斐波那契数列)
要使用long long超长整型存储
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
int main() {
int n;
int a, b;
long long d[51];
cin >> n;
d[1] = 1;
d[2] = 1;
for (int i = 3; i <= 50; i++) {
d[i] = d[i - 2] + d[i - 1];
}
while (n--) {
cin >> a >> b;
if (a > b)cout << 0 << endl;
//蜂房a走到蜂房b相当于蜂房1走到蜂房b-a+1
else cout << d[b - a + 1] << endl;
}
}
2045 不容易系列之(3)——LELE的RPG难题(递推)
若前n-1个格子已满足条件(每相邻两个不同,首尾不同),则第n个格子只有一种涂法
若前n-1个格子不满足条件(每相邻两个不同,首尾相同),说明第n-1个格子和首格相同,则第n个格子有2种涂法
f(n)=1f(n-1)+21*f(n-2)
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
int main() {
int n;
long long d[50] = { 0,3,6,6 };
for (int i = 4; i <= 50; i++) {
d[i] =d[i - 1]+2*d[i-2];
}
while (cin >> n) {
cout << d[n] << endl;
}
}
2046 骨牌铺方格(递推、斐波那契数列)
#include<iostream>
#include <stdio.h>
using namespace std;
int main() {
int n;
long long d[50] = { 0,1,2};
for (int i = 3; i <= 50; i++) {
d[i] =d[i - 1]+d[i-2];
}
while (cin >> n) {
cout << d[n] << endl;
}
}
2047 阿牛的EOF牛肉串(!!递推)
从第n位考虑,
① 当第n个是“O”时,依据限制条件,那么第n-1个不能为“O”,那n-1不为“O”就有两种情况了,即为“E”或者“F”,所以这种情况有f(n-2)*2个
② 当第n个不为“O”时,与第一步相同,也有两种情况,即为“E”或者“F”,所以这种情况有f(n-1)*2个.
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
int main() {
int n;
long long d[40] = { 0,3,8};
for (int i = 3; i <40; i++) {
d[i] =2*(d[i - 1]+d[i-2]);
}
while (cin >> n) {
cout << d[n] << endl;
}
}
2048 神、上帝以及老天爷(递推、错排)
不会
错排公式
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
int main() {
int n,c;
cin >> n;
long long f[21] = { 0,0,1,2 };
for (int i = 4; i <= 20; i++) {
f[i] = (i - 1)*(f[i - 1] + f[i - 2]);
}
while (n--) {
cin >> c;
double sum = 1;
for (int i = 1; i <= c; i++)
sum *= i;
double per = f[c]*100.0 / sum;
printf("%.2f%%\n", per);
}
}
2040 不容易系列之(4)——考新郎
注意使用longlong型,f(m)*Cnm
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
long long qp(int a) {
long long sum = 1;
for (int i = 1; i <= a; i++) {
sum *= i;
}
return sum;
}
int main() {
int n,c,m;
cin >> c;
//全错的可能性
long long f[21] = { 0,0,1,2 };
for (int i = 4; i <= 20; i++) {
f[i] = (i - 1)*(f[i - 1] + f[i - 2]);
}
while (c--) {
cin >> n>>m;
//Cnm
long long s = qp(n) / (qp(m)*qp(n - m));
printf("%lld%\n", s*f[m]);
}
}
2050 折线分割平面
1.直线切割平面:
第n条线最多与前面n-1条线都相交,且没有任何三条线相交于同一个点。则增加第n条直线共增加n-1个交点,增加n个平面
当n=1时,平面被分成2个部分;
当n=2时,增加2个,最多将平面分成2+2=4(个)部分;
当n=3时,增加3个,最多将平面分成2+2+3=7(个)部分;
当n=4时,增加4个,最多将平面分成2+2+3+4=11(个)部分;…;
所以当有n条直线时,最多将平面分成2+2+3+4+…+n=1+1+2+3+4+…+n=(n2 + n + 2) / 2
2.两条相互平行的线切割平面:
当第N次添加时,前面已经有2N-2条直线了,按我们上面讨论的知道,第N次添加时,第2N-1条直线和第2N条直线各能增加2(n-1)个交点,2(n-1)+1个平面。
所以第N次添加增加的面数是2[2(n-1) + 1] = 4n - 2 个。因此,总面数应该是1 +(2+4n-2)*n/2 = 2n^2 + 1
3.把每次加进来的平行边让它们一头相交
#include<iostream>
#include <stdio.h>
using namespace std;
int main() {
int c;
cin >> c;
while (c--) {
long long n;
cin >> n;
cout << 2 * n*n - n + 1 << endl;
}
}
2051 Bitset(2031)
十进制转二进制
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
void trans_r(int n,int r) {
int a, b;
if (n != 0) {
trans_r(n / r, r);
if (n%r > 9)
printf("%c", n%r + 'A');
else cout << n % r;
}
}
int main() {
int n;
while (cin >> n) {
trans_r(n,2);
cout << endl;
}
}
2052 Picture
#include<iostream>
#include <stdio.h>
using namespace std;
int main() {
int w, h;
while (cin >> w >> h) {
for (int i = 0; i <= w + 1; i++)
{
if(i==0||i==w+1)cout << '+';
else cout << '-';
}
cout << endl;
while (h--) {
for (int i = 0; i <= w + 1; i++) {
if (i == 0 || i == w + 1)cout << '|';
else cout << ' ';
}
cout << endl;
}
for (int i = 0; i <= w + 1; i++)
{
if (i == 0 || i == w + 1)cout << '+';
else cout << '-';
}
cout << endl;
cout << endl;
}
}
2053 Switch Game
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
int main() {
//求因数个数,奇数个最后则是亮,偶数个不亮
int n;
while (cin >> n) {
int a = 1;//因为循环只到n/2,会漏掉n本身,则从1开始计算。
for (int i = 1; i <= n / 2; i++) {
if (n%i == 0)
a++;
}
if (a % 2 == 1)cout << 1 << endl;
else cout << 0 << endl;
}
}
更快捷的方法是直接判断n是不是完全平方数,若是完全平方数则为1,否则为0
判断完全平方数的方法:判断(int)sqrt(n)*(int)sqrt(n)是否等于n
2054 A == B ?
判断两个数是否相等,这题坑会比较多,而且给的数值超过64位,所以要用字符串解决问题。
然后大概有这些坑:
1.给的样例前可能有无意义的0,例如002 02;
2.可能存在小数点,且小数点的数结尾可能存在无意义的0,例如2.00 2.0;
3.可能会有负数,要考虑符号问题,应该没有加号,反正我没考虑;
4.-0和0是相等的;
5.用字符串的存储数的时候要把字符串开到50000之多,否则会报错。
原文链接:https://blog.csdn.net/DarkFlameMuster/article/details/90523228
#include<iostream>
#include <stdio.h>
#include<String.h>
#include<algorithm>
#include<set>
using namespace std;
int main() {
char a[100000], b[100000];
int len_a, len_b, af, bf, ab, bb;
while (cin>>a>>b) {
len_a = strlen(a);
len_b = strlen(b);
af = bf = 0;
//去掉负号
if (a[0] == '-')af++;
if (b[0] == '-')bf++;
//去掉前面的0,af,bf表示小数点前第一个不为0的字符,若为0则放在小数点前一位
while (a[af] == '0'&&af<len_a-1)
af++;
if (a[af] == '.')
af--;
while (b[bf] == '0'&&bf < len_b - 1)
bf++;
if (b[bf] == '.')
bf--;
//查找有无小数点
int flag_a = 0;
for (int i = 0; i < len_a; i++) {
if (a[i] == '.')
flag_a = 1;
}
int flag_b = 0;
for (int i = 0; i < len_b; i++) {
if (b[i] == '.')
flag_b = 1;
}
//若有小数点去掉后面的0, ab, bb表示从后往前第一个不为0的字符
ab = len_a - 1;
if (flag_a == 1) {
while (a[ab] == '0')
ab--;
if (a[ab] == '.')
ab--;
}
bb = len_b - 1;
if (flag_b == 1) {
while (b[bb] == '0')
bb--;
if (b[bb] == '.')
bb--;
}
//对比
int flag = 0;
for (int i = af, j = bf; i <= ab&&j <= bb; i++, j++) {
//所指字符不同或长度不同
if (a[i] != b[j]||(i==ab&&j!=bb)||(i!=ab&&j==bb)) {
cout << "NO" << endl;
flag = 1;
}
}
if (flag == 0) {
if((a[0]=='-'&&b[0]=='-')||(a[0]!='-'&&b[0]!='-'))
cout << "YES" << endl;
else if ((a[0] == '-'&&b[0] != '-') || (a[0] != '-'&&b[0] == '-')) {
if (a[af] == '0'&&b[bf] == '0')
cout << "YES" << endl;
else cout << "NO" << endl;
}
}
}
}
2055 An easy problem
#include<iostream>
#include <stdio.h>
using namespace std;
int f(char x) {
if (x >= 'a'&&x <= 'z')
return (int)(x - 'a'+1)*(-1);
if (x >= 'A'&&x <= 'Z')
return (int)(x - 'A'+1);
}
int main() {
int n;
cin >> n;
while (n--) {
int y;
char x;
cin >> x >> y;
cout << y + f(x) << endl;
}
}