循环

循环

c++如何实现格式化输出

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int no=0,yes=0,yes_count=0;
    int n,k;
    cin>>n>>k;
    int i=1;
    int a;
    while(i<=n)
    {
        if((1.0)*i/k==i/k)
        {
            yes_count++;
            yes+=i;
        }
        else
        no+=i;
        i++;
    }
    cout<<setiosflags(ios::fixed)<<setprecision(1)<<(1.0)*yes/yes_count<<" "<<setiosflags(ios::fixed)<<setprecision(1)<<(1.0)*no/(n-yes_count);
    return 0;
}

1.输出空格用" "(中间加一个空格)
2.输出格式加在setiosflags()的括号内
3.ios::fixed实现浮点数以确定小数位数输出
4.调用cout的成员函数/作用相同的流操纵算子
precision setprecision(n)设置输出浮点数的精度为n
width setw(w)指定输出宽度为w个字符
setfill(c)指定以c字符填充不足的位数

高精度运算(阶乘之和)

出错点:

  1. 加法的surplus最多两位数,push_back的时候只许求模/整除一次即可
  2. 高精度乘法时的surplus可能有好几位数(乘的数可能是两位数),只求模/整除一次,有可能不够,导致过大的surplus保存在vector的一位int中,随着n的增大,雪球越滚越大,最终溢出,导致最终的结果出现负数
  3. vectora中的a是常指针
  4. 函数体传参时,注意使用地址传递,如果时拷贝传递,无法改变实际的值
  5. 注意过程中的溢出问题

DEBUG心得:

  1. 学会使用断点,跳过

不足之处:

  1. 使用了vector实现可变长度的“数组”,使用push_back()随时添加“数组”元素,但是带来了长度比较的麻烦
  2. 但是如果已知输入n的范围,可以直接定义(略大的)定长的数组,方便对齐,不需要长度比较
  3. 可以尝试使用c++的运算符重载
  4. 可以尝试实现高精度除法和高精度减法
#include <iostream>
#include <vector>
using namespace std;

void multiply(vector<int>*a,int b);
void add(vector<int> *a, vector<int>b);
void printV(vector<int>a);
//高精度算法:用数组存储
int main()
{
    vector<int>sum={0};
    vector<int>multiply1={1};
    vector<int> *p1=&multiply1;
    vector<int> *p2=&sum;
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        multiply(p1, i);
        add(p2,multiply1);
    }
    printV(sum);
    return 0;
}
void add(vector<int>* a, vector<int>b)
{
    int n1=a->size();
    int n2=b.size();
    long long all;
    int i;
    int surplus=0;
    for(i=0;i<n2&&i<n1;i++)
    {
        all=a->at(i)+b[i]+surplus;
        surplus=all/10;
        a->at(i)=all%10;
    }
    if(n2==n1+1){
        a->push_back((surplus+b[i])%10);
        surplus=(surplus+b[i])/10;
        while(surplus!=0)
        {
            a->push_back(surplus%10);//高精度加法里面其实不需要使用while循环
            surplus=surplus/10;  
        }   
    }
    else if(n2>n1+1)
    {
        while(i<n2)
        {
            a->push_back((surplus+b[i])%10);
            surplus=(surplus+b[i])/10;
            i++;
        }
        while(surplus!=0)
        {
            a->push_back(surplus%10);
            surplus=surplus/10;
        }
        
    }
    else if(n2==n1)
    {
        while(surplus!=0){
                a->push_back(surplus%10);
                surplus=surplus/10;
        }
        
    }
    else if(n2==n1-1)
    {
        int temp=(a->at(i)+surplus)/10;
        a->at(i)=(a->at(i)+surplus)%10;
        while(temp!=0){
            a->push_back(temp%10);
            temp=temp/10;
        }
    }
    else {
        while(i<n1&&surplus!=0)
        {
            int temp=(a->at(i)+surplus)/10;
            a->at(i)=(a->at(i)+surplus)%10;
            surplus=temp;
        }
        while(surplus!=0){
            a->push_back(surplus%10);
            surplus=surplus/10;
        }
        
    }
    return ;
}
void printV(vector<int>a){
    int n=a.size();
    for(int i=n-1;i>=0;i--)
    {
        cout<<a[i];
    }
}
void multiply(vector<int>*a,int b)
{
    int n=a->size();
    int i,surplus=0;
    for(i=0;i<n;i++)
    {
        int temp=((a->at(i))*b+surplus)/10;
        a->at(i)=((a->at(i))*b+surplus)%10;
        surplus=temp;
    }
    while(surplus!=0)
    {
        a->push_back(surplus%10);
        surplus=surplus/10;
    }
    return;
}

级数求和

  1. 出错点:整数的除法返回一个整数,如果不进行强制类型转换每次sum叠加都是0,会超时
  2. 思路:循环
#include <iostream>
#include <math.h>
using namespace std;
//正确代码
int main()
{
    double sum=0;
    int t;
    int k;
    cin>>k;
    for(t=1;;t++)
    {
        sum+=1.0/t;
        if(sum>k*1.0)
        break;
    }
    cout<<t;
    return 0;
}
//错误代码
int main()
{
    double sum=1;
    int t=2;
    int k;
    cin>>k;
    while(sum<k)
    {
        sum+=1.0/t;
        t++;
    }
    cout<<t;
    return 0
}
1. 直接忽略了t=1的情况,从2开始加,考虑的输入情况可能有失偏颇
2. t++之前sum已经大于k,所以应输出--t

质数判断

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;

bool isPrime(int);
void put(vector<int>);
int main()
{
    int l;
    cin>>l;
    vector<int>a;
    int sum=0;
    for(int i=2;;i++)
    {
        if(isPrime(i))
        {
        if(sum<l)
        {
            sum+=i;
            a.push_back(i);
        }
        if(sum==l)
            {put(a);break;}
        else if(sum>l)
        {
            sum-=i;
            a.pop_back();
            put(a);
            break;
        }
        
        }
    }
    return 0;
}
bool isPrime(int n)
{
    for(int i=2;i<=sqrt(n);i++)//注意这里应该i的判断条件应该加等号
    {
        if(n%i==0)
        return false;
    }
    return true;
}
void put(vector<int>a){
    int n=a.size();
    for(int i=0;i<n;i++)
        cout<<a[i]<<endl;
    cout<<n<<endl;
    return ;
}

找到范围内最大的回文质数

  • 注意点:
  1. 素数一定是奇数,偶数一定不是素数
  2. 大于等于4的偶数位的数字一定不是回文质数,一定是11的倍数
  3. 最大的回文质数是9989899(暂时不知道为什么),如果不加上这一限定条件,最后一个数据点一定会超时
//代码实现
#include <math.h>
#include <iostream>
using namespace std;

bool isPrime(long long n);
int len(int n);
bool isR(long long n);
int main()
{
    long long a,b;
    cin>>a>>b;
    if(b>9989899)
    b=9989899;
    if(a%2==0)a=a+1;
    for(long long i=a;i<=b;i+=2)
    {
        if(len(i)>=4&&len(i)%2==0)
        continue;
        if(!isR(i))
        continue;
        if(!isPrime(i))
        continue;
        cout<<i<<endl;
    }
    return 0;
}

bool isPrime(long long n)
{
    if(n%2==0&&n!=2)
    return false;
    for(long long i=3;i<=sqrt(n);i+=2)
    {
        if(n%i==0)
        return false;
    }
    return true;
}

bool isR(long long n)
{
    long long temp1=0;
    long long temp2=n;
    while(n!=0)
    {
        temp1=temp1*10+n%10;
        n=n/10;
    }
    if(temp1==temp2)
    return true;
    else
    return false;
}
int len(int n){
    int i=0;
    while(n!=0)
    {
        i++;
        n/=10;
    }
    return i;
}
posted @ 2023-01-26 20:06  5hithin  阅读(48)  评论(0)    收藏  举报