1、近似计算:PI/4,直到最后一项小于pow(10,-6);
#include <iostream>
#include <cmath>
using namespace std;
#define PI 3.1415926
int main() {
float sum = 0;
int n = 1;
int temp;
while (sum <= PI) {
sum += 1.0 / n * pow(-1, n + 1);
if (1.0/ n <= pow(10, -6))break;
n += 2;
}
temp=(1.0/n)*pow(10,6);
cout << floor(temp+0.5)*pow(10,-6);
return 0;
}
总结:floor()函数的使用是向下取整,+0.5就可以四舍五入。
2、阶乘之和:计算S=1!+…+n!的末六位
#include <iostream>
#include <cmath>
using namespace std;
int digui(int i){
if(i==1)return 1;
return i*digui(i-1);
}
int main() {
int sum=0;
int n;
int temp;
cin>>n;
for(int i=1;i<=n;i++){
sum+=digui(i);
}
temp=sum%1000000;
cout<<temp;
return 0;
}
总结:递归要在函数内找到一个出口这次i==1就是它的出口。
3、数据统计:利用while(cin>>x)来进行重复输入。然后利用EOF来结束并运行程序。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
#define INF 1000000
int main(){
int x,n=0,min=INF,max=-INF,s=0,kcase=0;
while(cin>>n&&n){
int s=0;
for(int i=0;i<n;i++){
cin>>x;
if(x<min)min=x;
if(x>max)max=x;
s+=x;
}
if(kcase)cout<<endl;
cout<<"Case"<<++kcase<<":"<<min<<" "<<max<<" "<<setiosflags(ios::fixed|ios::showpoint)<<setprecision(3)<<(double)s/n<<endl;
}
return 0;
}
总结:较为新颖的地方就是用到了里面的
setiosflags(ios::fixed|ios::showpoint)<<setprecision(3)
标题来保存小数点后三位,并保存小数点后的0;
4、水仙花数
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
#define INF 1000000
int main(){
int a,b,c,sum=0;
for(int i=100;i<=999;i++){
a=i/100;
b=(i/10)%10;
c=i%10;
sum=pow(a,3)+pow(b,3)+pow(c,3);
if(sum==i)cout<<i<<" ";
}
return 0;
}
5、韩信点兵:(待优化)
#include <iostream>
#include <string>
using namespace std;
int main(){
int a,b,c,kcase=1;
while (cin>>a&&cin>>b&&cin>>c){
for(int i=10;i<=100;i++){
if((i-a)%3==0&&(i-b)%5==0&&(i-c)%7==0){
cout<<"Case"<<kcase<<":"<<i;
break;
}
if(i==100){
cout<<"Case"<<kcase<<":"<<"No answer";
}
}
kcase++;
}
return 0;
}
6、倒三角形:通过建立坐标轴和利用二维数组进行相应绘画。
#include <iostream>
#include <string>
using namespace std;
char a[41][41];
void draw(int posx, int posy, int n) {
for (int i = 0; i < n; i++) {
a[posx][posy+i] = '#';
// cout<<"第"<<i+1<<"层";
for(int j=1;j<i+1;j++){
a[posx-j][posy+i]='#';
a[posx+j][posy+i]='#';
// cout<<j;
}
}
}
void printf(int posx,int n){
for (int i =n-1; i >=0 ; --i) {
for (int j=posx-n+1;j<posx+n;j++) {
cout<<a[j][i];
// cout<<endl;
}
cout<<endl;
}
}
int main() {
memset(a,' ',sizeof (a));
int posx=21,posy=0,n;
cin>>n;
draw(posx,posy,n);
printf(posx,n);
return 0;
}
总结:
1、memset(数组名,“ ”,sizeof(数组名)),进行二维数组初始化。
2、建立全局数组变量就可以在函数内直接修改。
3、在建立二维坐标轴的时候要搞清楚谁是x,谁是y,否则无论打印还是输出都不好弄。
7、子序列的和:关键是在考整数溢出的问题,int的范围-2147483648 ~ 214748364,而当n=655360是乘方后将达到12位,容易造成溢出。
#include <iostream>
#include <string>
#include<cmath>
#include <iomanip>
using namespace std;
#define INF 100000
int main() {
long long n, m, kcase = 1;
float sum = 0;
while (cin >> n && cin >> m && n != 0 & m != 0) {
for ( n; n <= m; ++n) {
n*=INF;
n/=INF;
sum += pow(pow(n,2),-1);
}
cout << "Case " << kcase << ":" << setiosflags(ios::fixed | ios::showpoint) << setprecision(5) << sum;
kcase++;
sum=0;
}
return 0;
}
总结:
1、应该考虑到除不尽的小数,所以要对整数进行保留五位小数点的操作,即一乘一除。
2、四舍五入的背诵:头文件是:iomanip,
函数内容是<<setiosflags(ios::fixed|ios::showpoint)<<setprecision(n)
8、分数化小数:主要就是两个int类型的相乘的话就要*1.0化成浮点型的。
#include <iostream>
#include <string>
#include<iomanip>
using namespace std;
int main() {
int a,b,c,kcase=1;
float s;
while(cin>>a&&cin>>b&&cin>>c&&a!=0&&b!=0&&c!=0){
s=1.0*a/b;
cout<<"Case "<<kcase<<":"<<setiosflags(ios::fixed|ios::showpoint)<<setprecision(c)<<s;
kcase++;
}
return 0;
}
总结:
四舍五入的函数就是好用;
9、排列:用0-9组成3个三位数字,且每个数字恰好用一次,同时abc=def=ghi=1:2:3;
#include <iostream>
#include <string>
using namespace std;
int vis[10]={0};
void getnum(int list){
int a=list/100;
int b=(list/10)%10;
int c=list%10;
vis[a]+=1;
vis[b]+=1;
vis[c]+=1;
}
int main() {
int abc,def,ghi;
for(int i=123;i<=329;i++){
abc=i;
def=i*2;
ghi=i*3;
getnum(abc);
getnum(def);
getnum(ghi);
for(int j=1;j<10;j++){
if(vis[j]==0)break;
if(j==9)cout<<abc<<" "<<def<<" "<<ghi<<endl;
}
memset(vis,0,sizeof (vis));
}
return 0;
}
总结:
关键在于利用数组来记录数字的使用情况,同样是利用到全局数组来进行记录。
还有就是利用menset()函数来重复初始化数组。
10、for循环的小细节:
#include <iostream>
#include <string>
using namespace std;
int main() {
int n;
cin>>n;
for(int i=2;i<=2*n;i+=2){
cout<<i<<endl;
}
return 0;
}
在for(;;i+=2)才可以,如果只是i+2,就会陷入死循环。
11、开灯问题:有n盏灯编号1~n,第一个人全开了,后面的人按自己编号的倍数开关灯。
#include <iostream>
#include <string>
using namespace std;
#define maxon 1010
int lantern[maxon];
void turnOff(int n, int k) {
memset(lantern, 0, sizeof lantern);
for (int i = 2; i <= k; i++) {
for (int j = 1; j <= n; j++) {
if (j % i == 0) {
if (lantern[j] == 0)
lantern[j] = -1;
else lantern[j] = 0;
}
}
}
for (int h = 1; h <= n; h++) {
if (lantern[h] == 0)cout << h << " ";
}
}
int main() {
int n, k;
cin >> n >> k;
turnOff(n, k);
return 0;
}
总结:
1、memset()在int方面只能弄-1和0,不能弄1,除非是字符‘1’。且它的头文件名是<string>
2、int a[maxon]
表示声明了一个包含maxon个整型变量的数组,其中maxon只能是常数,不能是变量。
3、定义数组的时候可以定义在main()
外面这样数组才可以开的很大,放在里面容易异常退出。
4、数组交换可以用memcpy(b,a,sizeof(a))
表示把a数组复制到b中。
12、蛇形填数:下左上右在二维数组里面填数。
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
#define maxn 1010
int snakeFill[maxn][maxn];
int main() {
int n,x,y,count=2;
memset(snakeFill,0,sizeof (snakeFill));
cin>>n;
snakeFill[x=0][y=n-1]=1;
while (count<n*n){
while(1+x<n&&!snakeFill[x+1][y])snakeFill[++x][y]=count++;
while(y-1>=0&&!snakeFill[x][y-1])snakeFill[x][--y]=count++;
while(x-1>=0&&!snakeFill[x-1][y])snakeFill[--x][y]=count++;
while(y+1<n&&!snakeFill[x][y+1])snakeFill[x][++y]=count++;
}
for(int i=0;i<n;i++){
for (int j = 0; j < n; ++j) {
if(snakeFill[i][j]<10)cout<<snakeFill[i][j]<<" "<<"\t";
else
cout<<snakeFill[i][j]<<"\t";
}
cout<<endl;
}
return 0;
}
总结:
1、用while循环来做判断条件,与此同时利用++来更改变量值,这是我要学习的地方。
14、竖式输出:输入一个数字集合,然后去找三位数乘两位数的算式,且这些数字属于特定集合,如果符合条件就排版输出,并在最后输出解的总数。
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
int main() {
char s[20], buf[99];
cin >> s;
int x, y, z, count = 0;
for (int abc = 100; abc < 999; ++abc) {
for (int i = 10; i < 99; ++i) {
x = abc * (i % 10);
y = abc * (i / 10);
z = abc * i;
sprintf(buf, "%d%d%d%d%d", abc, i, x, y, z);
int ok = 1;
for (int j = 0; j < strlen(buf); j++) {
if (strchr(s, buf[j]) == nullptr)ok = 0;
}
if (ok) {
cout << "<" << ++count << ">" << endl;
cout << " " << abc << endl;
cout << "x " << i << endl;
cout << "-----" << endl;
cout << setw(5) << setfill(' ') << x << endl;
cout << setw(4) << setfill(' ') << y << endl;
cout << "-----" << endl;
cout << setw(5) << setfill(' ') << z << endl;
}
}
}
cout << '\n' << "The number of solutions =" << count;
return 0;
}
总结:
1、新学的sprintf()
函数来进行数组赋值,格式为:sprintf(buf, "%d%d%d%d%d", abc, i, x, y, z);
2、strlen()
函数获取数组的实际长度(包括一个‘\0’
),格式为:strlen(buf)
3、strchr()
函数用于单个字符的查找,返回nullptr,
或true
;格式为:
for (int j = 0; j < strlen(buf); j++) {
if (strchr(s, buf[j]) == nullptr)ok = 0;
}
4、setw()
函数,用于保留几位数字,不够的setfill()
函数来凑,头文件为<iomanip>
,
格式为:cout << setw(5) << setfill(' ') << x << endl;
15、Tex中的引号:将论文中的‘ “” ’改成``
#include <iostream>
#include <string>
using namespace std;
int main() {
int c,q=1;
string s;
while((c=getchar())!=EOF){
if(c=='"'){
s=q ? "``":"''";
cout<<s;
q=!q;
}
else{
cout<<(char)c;
}
}
return 0;
}
总结:
1、在利用while循环加getchar()进行单个字符的获取和连续输入
2、利用?:来判断选择左右``,同时用q=!q;来进行调换。
3、注意点:因为c得到的int型的,输出时记得转换成char型
16、字符纠正:把在键盘上往右输错的字符给纠正出来不能出界。
#include <iostream>
#include <string>
using namespace std;
char arr[]="`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
int main() {
int c,i;
while((c=getchar())!=EOF){
if(c==32)putchar(char(32));
for(i=1;arr[i]&&arr[i]!=c;i++);
if(arr[i]==c)putchar((char)arr[i-1]);
else putchar((char)arr[i]);
}
return 0;
}
总结:
1、像这种可以每输入一个字符就可以输出一个字符的程序,可以考虑使用getchar()
和putchar()
函数。
2、利用常量数组,可以大大方便代码的使用,尤其是考虑到这种有相邻关系的题目。
3、个人感觉这个代码还有一个精细的地方就是利用for循环,来进行无语句的搜寻。
17、回文词:输入一个字符串判断它是否为回文串和镜像串。
#include <iostream>
#include <string>
using namespace std;
char arr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
char Arr[] = "A000300HIL0JM0O0002TUVWXY51SE0Z0080";
char temp[99];
char temp2[99];
char temp3[99];
int main() {
int c, i, count = 0, sign = 1, sign1 = 1;
while ((c = getchar()) != EOF) {
temp3[count] = (char) c;
temp2[99 - count] = (char) c;
for (i = 0; arr[i] && arr[i] != c; i++);
if (arr[i])temp[count] = Arr[i];
count++;
for (int j = 0; j < count + 1; j++) {
if (temp[j] != temp3[j]) {
sign = 0;
}
if (temp3[j] != temp2[99 - count + j])sign1 = 0;
}
}
for (int k = 0; k < count + 1; k++) {
cout << temp3[k];
}
if (sign && sign1) {
cout << "--is a mirrored palindrome.";
}
if (!sign1) {
cout << "--is not a palindrome.";
}
if (sign1) {
cout << "--is a regular palindrome.";
}
if (sign) {
cout << "--is a mirrored string.";
}
return 0;
}
总结:
1、这边利用到了常量数组来进行对应判断。
18、得分:![在这里插入图片描述](https://img-blog.csdnimg.cn/20210326155406836.jpeg)
#include <iostream>
#include <string>
#define INF 100000
using namespace std;
int main() {
int c,s=0,count=0;
while((c=getchar())!='#'){
if(c=='O'){
count++;
s+=count;
}
else if(c=='X'){
count=0;
}
}
cout<<s;
return 0;
}
19、![在这里插入图片描述](https://img-blog.csdnimg.cn/20210326165559728.jpeg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RaYTk5MDk5,size_16,color_FFFFFF,t_70)
#include <iostream>
#include <string>
#define maxn 1010
float a[4]={12.01,1.008,16.00,14.01};
float arr[maxn];
using namespace std;
int main() {
double s=0;
int c;
int i=0;
memset(arr,0,sizeof (arr));
while((c=getchar())!='#'){
switch (c) {
case 'C':
arr[i]=a[0];
s+=a[0];
break;
case 'H':
arr[i]=a[1];
s+=a[1];
break;
case 'O':
arr[i]=a[2];
s+=a[2];
break;
case 'N':
arr[i]=a[3];
s+=a[3];
break;
default:
c=c-'0';
s=s+arr[i-1]*1.0*(c-1);
break;
}
i++;
}
cout<<s;
return 0;
}
总结:
1、getchar()返回的是int类型,而‘N’也是int类型的Ascll码。
2、getchar()返回的int类型变量可以直接使用,但是其值是ascll码。
20、数数字,把整数写在一起。数0-9各出现多少次。
#include <iostream>
#include <string>
#define maxn 1010
int arr[10];
using namespace std;
int main() {
int c;
memset(arr, 0, sizeof(arr));
while ((c = getchar()) != '#') {
c = c - '0';
arr[c] += 1;
}
for (int i = 0; i < 10; i++) {
cout << arr[i] << " ";
}
return 0;
}
总结
1、利用的数字与数组的对应关系。来进行加数。
21、猜字符:输入一段字符,并输入另一段字符,进行逐个字符校验。
#include <iostream>
#include <string>
using namespace std;
#define maxn 1010
char s[maxn], computer[maxn];
int win, lose;
int left1, chance;
void guess(char a){
int bad=1;
for(int i=0;i<strlen(computer);i++){
// cout<<a;
if(a==computer[i]){
bad=0;
left1--;
computer[i]=' ';
}
}
if(bad)--chance;
if(!left1)win=1;
if(!chance)lose=1;
}
int main() {
int rnd;
while(cin>>rnd&&rnd!=-1){
cin>>computer;
cin>>s;
cout<<"Round"<<rnd<<":"<<endl;
win=lose=0;
left1=strlen(computer);
chance=7;
for (int i = 0; i <strlen(s) ; ++i) {
guess(s[i]);
if(win||lose)break;
}
if(win)cout<<"You win"<<endl;
else if(lose)cout<<"You lost"<<endl;
else cout<<"You chickened out"<<endl;
}
return 0;
}
总结:
1、利用全局变量来避免指针的传递。
2、采用全局变量来进行胜负的标志。利用整型变量的0,1来对结果进行划分。