1、计算一个数在不同的进制下的阶乘的位数
阶乘位数的公式:log(xy) = log(x) + log(y), 所以100的阶乘:log(1) + log(2) + ....log(100)
最后转化成不同的进制:最后除以log(base)后 +1 就好了(base指的是进制)
需要注意的是,开数组的时候要开double,否则是错的
代码:
double a[1000005] = {0};
void cal () {
for (int i = 1; i <= 1000005; i ++) {
a[i] = a[i - 1] + log10(1.0 * i);
}
}
int main () {
int cas;
int n, base;
scanf("%d", &cas);
cal();
for (int t = 1; t <= cas; t ++) {
scanf("%d%d", &n, &base);
printf("Case %d: %d\n", t, (int)(a[n] / log10(base * 1.0) + 1));
}
return 0;
}
2、计算任意两个日期之间有几个2月29日
首先,判断第一个日期在不在2月之前(2月之前指的是要是闰年,那就是2月29号包括29号之前,平年就是28号包括28号之前)
然后,判断第二个日期在不在2月之后
最后,第二个日期之前有几个闰年减去第一个日期之前有几个闰年就是答案
代码:
char m[12][20] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
map<string, int> maps;
int cal(int x) {
return x / 4 - x / 100 + x / 400;
}
int main() {
for(int i = 0; i < 12; ++i) {
maps[m[i]] = i + 1;
}
int T, nT = 0;
scanf("%d", &T);
while(T--) {
char s[20];
int m1,d1,y1,m2,d2,y2;
scanf("%s%d,%d", s, &d1, &y1);
m1 = maps[s];
scanf("%s%d,%d", s, &d2, &y2);
m2 = maps[s];
if(m1 == 1 || m1 == 2) y1--;
if(m2 == 1 || m2 == 2 && d2 < 29) y2--;
int ans = cal(y2)- cal(y1);
printf("Case %d: %d\n", ++nT, ans);
}
return 0;
}
3.方程思想,一元三次方程求根
题意:一块纸板,给出长L和宽W,要求四个角减去x*x的小正方形,x可以是任意的,减掉之后,纸板折成一个无盖的长方体,求出最大的容积V
列出V的方程:V = (L-2x) * (W-2x)* x
可以化简方程得到V = 4x^3 - 2(L+W)x^2+LWx
求导得到:12x^2 - 4(L+W)x+LW
带入求根公式-b-sqrt(b^2 - 4ac)/2a就好了
代码:
int main(){
int t;
scanf("%d",&t);
double l, w;
double a, b, c, d, x;
for (int i = 1; i <= t; i ++) {
scanf("%lf%lf", &l, &w);
a = 12,b = -4 * (l + w),c = l * w;
x = (-b - sqrt(b * b- 4 * a * c)) / 24;
printf("Case %d: %.10lf\n", i, (l - 2 * x) * (w - 2 * x) * x);
}
return 0;
}
4、二进制转化为十进制
题意:给出十进制数和二进制数,要求判断两者是不是一样
格式为:
2
192.168.0.100
11000000.10101000.00000000.11001000
65.254.63.122
01000001.11111110.00111111.01111010
二进制转十进制函数:
int change(int x) {
int i = 0;
int ans = 0;
do {
ans += x % 10 * pow(2, double(i));
x /= 10;
i ++;
}while(x != 0);
return ans;
}
代码:
int change(int x) {
int i = 0;
int ans = 0;
do {
ans += x % 10 * pow(2, double(i));
x /= 10;
i ++;
}while(x != 0);
return ans;
}
int main() {
int cas;
scanf("%d", &cas);
for (int t = 1; t <= cas; t ++) {
int a,b,c,d;
int a1,b1,c1,d1;
scanf("%d.%d.%d.%d", &a, &b, &c, &d);
scanf("%d.%d.%d.%d", &a1, &b1, &c1, &d1);
a1 = change(a1); b1 = change(b1);
c1 = change(c1); d1 = change(d1);
if(a==a1&&b==b1&&c==c1&&d==d1)
printf("Case %d: Yes\n", t);
else printf("Case %d: No\n", t);
}
return 0;
}
5.题意:给出圆的半径,求出一个圆占用几个格子
.
分析:应该来说不难的这个题目,就是想不到,在方格纸上花了一个圆以后,只要是边把一个小方格占用了。那就算是整个占用了。那么可以从第一个格子开始算,用函数ceil(取到一个大于等于该数的最小整数)计算占用几个格子
代码:
int main() {
__int64 r, ans = 0;
scanf("%I64d", &r);
for(__int64 i = 0; i < r; ++i) {
ans += (int)ceil(sqrt(r * r - i * i));
}
ans *= 4;
printf("%I64d\n", ans);
return 0;
}