P1010 幂次方
一、题目
https://www.luogu.org/problemnew/show/P1010
二、代码
#include<bits/stdc++.h> using namespace std; // 根据2的几次幂进行分解 string decompose(int num) { if(num==0) { return "0"; } string s = ""; int exp = 0; // 指数,比如2=2^1,则指数为1 do { if(num & 1) // 判断奇数 { // num=2时,exp==1才为真 string tmp1 = exp==1 ? "2" : "2("+decompose(exp)+")"; string tmp2 = s=="" ? "" : "+"; // 拼接字符串,依题意,要把低次方接在后面 s = tmp1 + tmp2 + s; } exp++; } while(num >>= 1);//每次向右移一位,即除以2 return s; } int main() { int x; cin>>x; cout<<decompose(x)<<endl; return 0; }
P1022 计算器的改良
一、题目
https://www.luogu.org/problemnew/show/P1022
二、代码
#include<bits/stdc++.h> using namespace std; int main() { int coe = 0; // coe * x = value, coe即为x的系数 int value = 0; int pos = -1; // 数值位于等号左边的数为负(移到右边即为正),位于等号右边的数为正 char c = getchar(); int num = 0; // 当前读入的数值 int sign = 1; // 当前数值符号, char x; // 未知数,26个小写字母之一 while(true) { if (c>='a' && c<='z') { x = c; if (num == 0) { // 系数为1 coe += -pos * sign; } else { coe += -pos * sign * num; //系数左边为正,右边为负,所以pos要取负 } num = 0; sign = 1; } else if (c == '-') { value += pos * sign * num; num = 0; sign = -1; } else if (c == '+') { value += pos * sign * num; num = 0; sign = 1; } else if (c >= '0' && c <= '9') { num = num * 10 + c - '0'; } else if (c == '=') { value += pos * sign * num; num = 0; sign = 1; pos = -pos; //等号右边pos为正 } else // 换行的时候,要把最后的数(如果有)累加到valu { value += pos * sign * num; break; } c = getchar(); } double ans = double(value) / coe;//计算ans printf("%c=%.3f", x, ans == 0 ? abs(ans) : ans);//这涉及一个很坑的地方:C++里0除以一个负数值为-0,专门避免这种情况 return 0; }
UVA524 素数环
一、题目
https://www.luogu.org/problemnew/show/UVA524
二、分析
例1:以n = 4为例。n = 4的排列有
1,2,3,4 相邻两个数相加都是素数,符合题意
1,2,4,3 2和4相加不是素数,不符合题意
1,3,2,4 2和4相加不是素数,不符合题意
1,3,4,2 4和2相加不是素数,不符合题意
1,4,2,3 4和2相加不是素数,不符合题意
1,4,3,2 相邻两个数相加都是素数,符合题意。
所以正确的答案为
1,2,3,4
1,4,3,2
例2:以n = 5为例。n = 5的排列有
1,2,3,4,5 4和5相加不是素数,不符合题意
1,2,3,5,? 3和5相加不是素数,不符合题意
1,2,4,? 2和4相加不是素数,不符合题意
1,2,5,3,? 5和3相加不是素数,不符合题意
1,2,5,4,? 5和4相加不是素数,不符合题意
1,3,? 1和3相加不是素数,不符合题意
1,4,2,? 4和2相加不是素数,不符合题意
1,4,3,2,5 5和1相加不是素数,不符合题意
1,4,3,5,? 3和5相加不是素数,不符合题意
1,4,5,? 4和5相加不是素数,不符合题意
1,5,? 1和5相加不是素数,不符合题意
所以n=5时,没有答案。
三、代码
#include<bits/stdc++.h> using namespace std; int n; int a[100]; int prime[100]; bool visited[100]; //visited[num]用来标记num是否被使用了 // pos为数组下标 void dfs(int pos) { // num为数组中的数 for(int num=2; num<=n; num++) { // 如果这个数已经使用,则不能再用 if(visited[num]) { continue; } if(prime[a[pos-1] + num]) //当前数num与上一个数的和为素数 { visited[num] = true; // 标记 a[pos] = num; // 存储,后面需要打印出来 if(pos == n) // 放完了n个数 { if(prime[a[pos] + 1]) //这是一个环,所以要计算最后一个数与第一个数1的和 { for(int j = 1; j < n; j++) { printf("%d ",a[j]); } printf("%d ", a[n]); //这里很恶心,行末不能有空格 } } else { dfs(pos + 1); } visited[num] = false; //回溯 } } } int main() { // 素数打表 prime[2]=prime[3]=prime[5]=prime[7]=prime[11]=prime[13]=prime[17]=prime[19]=prime[23]=prime[29]=prime[31]=true; //先处理一下素数 int cnt = 0; // 输出的第几组数据 while(scanf("%d",&n) == 1) { cnt++; printf("Case %d: ",cnt); a[1] = 1; //第一个数是1 visited[1] = true; // 这一句可写可不写,因为1就是第一个数 dfs(2); //从第二个数开始搜 cout << endl; } return 0; }
P4326 求圆的面积
一、题目
https://www.luogu.org/problemnew/show/P4326
二、分析
COCI是Crotian Open Competition in Informatics, 即克罗地亚信息学公开赛。
本题的坑点在于有些人不知道所谓的出租车几何下的“圆”其实是一个正方形:
上面这个“圆”中,中心点到边上的任意一点的距离都为|x1 - x2| + |y1 - y2| = 4。
这个“圆”是由上下两个三角形组成的,每个三角形的面积为2r * r / = r * r,所以“圆”的面积为2 * r * r。
#include <iostream> #include <cstdio> using namespace std; const double pi = 3.141592653589793; int main() { double r; cin >> r; printf("%.6f ", pi * r * r); printf("%.6f ", 2 * r * r); return 0; }
P1009 阶乘之和
#include<iostream> using namespace std; int a[2000]; int c[2000]; const int maxDigit=1000; //最大位数,调试时可设n=4,maxDigit=3 // 阶乘相加 void add(int *a,int *c) { int carry = 0; // 比如1!+2!+3!+4! // i=1时,c[1]=1!=1 // i=2时,c[1]=1+2!=3 // i=3时,c[1]=3+3!=9 // i=4时,c[1]=9+4=13,carry=1,c[1]=3,c[2]=c[2]+a[2]+carry=0+2+1=3 for(int i = 1; i <= maxDigit; i++) { c[i] += (a[i] + carry); carry = c[i]/10; c[i] %= 10; } } //求阶乘 void fact(int *a,int num) { int carry = 0; // 进位 for(int i=1; i <= maxDigit; i++) { // 从高位往低位存储数据,比如5!=120,则a[4]=a[5]=...=0,a[3]=1,a[2]=2,a[1]=0 a[i] = a[i] * num + carry; carry = a[i] / 10; a[i] %= 10; } } int main() { int n; cin >> n; a[1] = 1; for(int i=1;i<=n;i++) { fact(a, i); add(a, c); } bool flag = false; // 当碰到第一个非0时,更新为true for(int i = 1000; i >= 1; i--) { // 左边的0不要打印出来,从第一个非0数字开始打印 // 比如000……000120,打印出120 if(c[i] != 0) { flag = true; } if(flag) { cout << c[i]; } } return 0; }
P1007 独木桥
#include <iostream> #include <cstdio> using namespace std; int main() { int n,l,p,maxT=0,minT=0; scanf("%d%d",&l,&n); for(int i=1;i<=n;i++) { scanf("%d",&p); maxT=max(maxT,max(l+1-p,p)); minT=max(minT,min(l+1-p,p)); } printf("%d %d",minT,maxT); return 0; }
P1002 过河卒
#include<iostream> using namespace std; long long a[30][30]={0},n,m,my,mx; int main() { cin >> n >> m >> my >> mx;//输入数据 // 整个棋盘往右往下挪两格,这样马处于原点(挪移后 // 变成(2,2)点,往左上方跳不会出现数组越界的情况 n += 2; // n行 m += 2; // m列 my += 2;// 马位于第几行 mx += 2;// 马处于第几列 for(int r = 2; r <= n; r++) // 共有n+1行 { for(int c = 2; c <= m; c++) // 共有m+1列 { a[r][c] = a[r - 1][c] + a[r][c - 1]; // 左侧的数 + 上方的数 a[2][2]=1; // 要初始化为1,若为0后面全是0 // 马的9个控制点 a[my][mx]=0;// 马本身的位置 a[my + 2][mx + 1]=0; a[my + 2][mx - 1]=0; a[my - 2][mx + 1]=0; a[my - 2][mx - 1]=0; a[my + 1][mx + 2]=0; a[my + 1][mx - 2]=0; a[my - 1][mx + 2]=0; a[my - 1][mx - 2]=0; } } cout <<a[n][m]; return 0; }