2023西工大NOJ (C语言版) 持续更新ing

目录

前言

入门题

Hello World

A+B

数据类型大小及范围

平均值

进制转换

浮点数输出

动态宽度输出

计算地球上两点之间的距离

风寒指数

乘数模

组合数

余数和

佩尔数

可变参数累加

可变参数平均

简单题

颜色模型转换

方阵

分数的加、减、乘、除

操作数

比率

级数和

对称数

倍数和

最大数字

毕达哥拉斯三元组

竖式乘法

查找数列

俄罗斯农夫乘法

哈沙德数

基思数

二进制表示

冰雹数列

中等题

幂数模

倒水

好数字

阶乘倍数

方案数

素数

光线追踪

运动会


前言

代码均可AC,易错总结参见我的博客 NOJ(C)易错总结 (annesede.github.io)

部分题目由于过于简单一次性AC,未能考虑可读性(其实是懒得改)。

题目分类如下,请按题目名称查找:

  • 入门题:只涉及基本的输入输出
  • 简单题:不涉及算法但有较多易错点
  • 中等题:涉及简单的算法或数学知识
  • 难题:涉及复杂的算法或数学知识

入门题

Hello World

#include<stdio.h>

int main(){
    printf("Hello World");
    return 0;
}

A+B

#include<stdio.h>

int main(){
    int a = 0, b = 0;
    scanf("%d %d",&a,&b);
    printf("%d",a+b);
    return 0;
}

数据类型大小及范围

#include <stdio.h>
#include <limits.h>

int main(){
    int id = 0;
    scanf("%d",&id);
    switch (id) {
        case 1: // char
            printf("%llu,%d,%dn",sizeof(char),CHAR_MIN,CHAR_MAX);
            break;
        case 2: // unsigned char
            printf("%llu,%u,%un",sizeof(unsigned char),0,UCHAR_MAX);
            break;
        case 3: // short
            printf("%llu,%hd,%hdn",sizeof(short),SHRT_MIN,SHRT_MAX);
            break;
        case 4: // unsigned short
            printf("%llu,%hu,%hun",sizeof(unsigned short),0,USHRT_MAX);
            break;
        case 5: // int
            printf("%llu,%d,%dn",sizeof(int),INT_MIN,INT_MAX);
            break;
        case 6: // unsigned int
            printf("%llu,%u,%un",sizeof(unsigned int),0,UINT_MAX);
            break;
        case 7: //long
            printf("%llu,%ld,%ldn",sizeof(long),LONG_MIN,LONG_MAX);
            break;
        case 8: // unsigned long
            printf("%llu,%u,%lun",sizeof(unsigned long),0,ULONG_MAX);
            break;
        case 9: // long long
            printf("%llu,%lld,%lldn",sizeof(long long),LLONG_MIN,LLONG_MAX);
            break;
        case 10: // unsigned long long
            printf("%llu,%u,%llun",sizeof(unsigned long long),0,ULLONG_MAX);
            break;
    }
    return 0;
}

平均值

#include <stdio.h>

int main(){
    int a = 0, b = 0;
    scanf("%d %d",&a,&b);
    int c = ((b-a)>>1)+a;
    printf("%d",c);
    return 0;
}

进制转换

#include <stdio.h>

int main(){
    unsigned int a = 0;
    scanf("%d",&a);
    printf("%X,%o",a,a);
    return 0;
}

浮点数输出

#include <stdio.h>

int main(){
    double a = 0.0f;
    scanf("%lf",&a);
    printf("%.6lf,%.2lf,%.8lf",a,a,a);
    return 0;
}

动态宽度输出

#include <stdio.h>

int main(){
    int n = 0, m = 0, k = 0;
    scanf("%d %d",&n,&m);
    int tmp = n;
    while (tmp) {
        tmp /= 10;
        ++k;
    }
    for (int i = 0; i < m-k; ++i) {
        printf("%d",0);
    }
    printf("%d",n);
    return 0;
}

计算地球上两点之间的距离

#include <stdio.h>
#include <math.h>
#define RADIUS 6371.000000
#define PI 3.1415926

int main(){
    double phi1, phi2, lambda1, lambda2, distance;
    scanf("%lf %lf",&phi1,&lambda1);
    scanf("%lf %lf",&phi2,&lambda2);
    phi1 = phi1*PI/180;
    phi2 = phi2*PI/180;
    lambda1 = lambda1*PI/180;
    lambda2 = lambda2*PI/180;
    double havRatio = (1-cos(phi2-phi1))/2+cos(phi1)*cos(phi2)*(1-cos(lambda2-lambda1))/2;
    distance = asin(sqrt(havRatio))*2*RADIUS;
    printf("%.4lfkm",distance);
    return 0;
}

风寒指数

#include <stdio.h>
#include <math.h>

int main(){
    double v,T;
    scanf("%lf %lf",&v,&T);
    int chill = 13.12f+0.6215f*T-11.37f*pow(v,0.16f)+0.3965f*T*pow(v,0.16f)+0.5f;
    printf("%d",chill);
    return 0;
}

乘数模

#include <stdio.h>

int main(){
    long long a,b,m,r;
    scanf("%lld %lld %lld",&a,&b,&m);
    r = ((a%m)*(b%m))%m;
    printf("%lld",r);
    return 0;
}

组合数

#include<stdio.h>

int main(){

    int cnt = 0, n, m;
    scanf("%d",&n);

    for(int a = 0; a <= 9; ++a){
        for(int b = 0; b <= 9; ++b){
            for(int c = 0; c <= 9; ++c){
                for(int d = 0; d <= 9; ++d){
                    m = a+b+c+d;
                    if (m == n){
                        ++cnt;
                    }
                }

            }
        }
    }

    printf("%d",cnt);
    return 0;
}

余数和

#include <stdio.h>

int main() {
    unsigned int sum = 0, n, k;
    scanf("%u %u",&n,&k);
    for (unsigned int i = 1; i <= n; ++i) {
        sum += k%i;
    }
    printf("%u",sum);
    return 0;
}

佩尔数

#include <stdio.h>

int PA(int n){
    if (n == 0) return 0;
    else if (n == 1) return 1;
    return 2*PA(n-1)+PA(n-2);
}

int PB(int n){
    int p0 = 0, p1 = 1, pn;
    for (int i = 0; i <= n; ++i) {
        if (i == 0) pn = p0;
        else if (i == 1) pn = p1;
        else {
            pn = 2 * p1 + p0;
            p0 = p1;
            p1 = pn;
        }
    }
    return pn;
}

int main() {
    int n, p;
    scanf("%d",&n);
    if (n&1) p = PA(n);
    else p = PB(n);
    printf("%d",p);
    return 0;
}

可变参数累加

#include <stdio.h>
#include <stdarg.h>

int sum(int start,...){
    va_list vaList;
    int sum = 0;
    va_start(vaList,start);
    while (start){
        sum += start;
        start = va_arg(vaList,int);
    }
    va_end(vaList);
    return sum;
}

int main() {
    int a,b,c,d,e,f;
    scanf("%d %d %d %d %d %d",&a,&b,&c,&d,&e,&f);
    int sumMinus = sum(a,b,0) - sum(c,d,e,f,0);
    printf("%d",sumMinus);
    return 0;
}

可变参数平均
 

#include <stdio.h>
#include <stdarg.h>

double avg(int num,...){
    va_list vaList;
    double sum = 0.0f;
    va_start(vaList,num);
    for (int i = 0; i < num; ++i) {
        sum += va_arg(vaList,int);
    }
    va_end(vaList);
    return sum/num;
}

int main() {
    int a,b,c,d,e;
    scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);
    double avgMinus = avg(2,a,b) - avg(3,c,d,e);
    printf("%.4f",avgMinus);
    return 0;
}

简单题

颜色模型转换

#include <stdio.h>
#include <stdio.h>
#include <math.h>

double findmax(double a, double b, double c) {
    return a >= b ? (a >= c ? a : c) : (b >= c ? b : c);
}

double findmin(double a, double b, double c) {
    return a <= b ? (a <= c ? a : c) : (b <= c ? b : c);
}

int main()
{
    int R, G, B;
    double r, g, b;
    double max, min;
    double H, S, V;

    scanf("%d %d %d",&R,&G,&B);

    r = (double)((R > 0 ? R : 0) / 255.0f);
    g = (double)((G > 0 ? G : 0) / 255.0f);
    b = (double)((B > 0 ? B : 0) / 255.0f);
    max = findmax(r, g, b);
    min = findmin(r, g, b);

    V = max;

    if (max < 1e-9) {
        S = 0.0f;
    }
    else {
        S = (max - min) / max;
    }

    if (max - min < 1e-9) {
        H = 0.0f;
    }
    else {
        if (max == r) {
            H = 60.0f * (g - b) / (max - min);
        }
        else if (max == g) {
            H = 60.0f * (2.0f + (b - r) / (max - min));
        }
        else if (max == b) {
            H = 60.0f * (4.0f + (r - g) / (max - min));
        }
        else {
            return -1;
        }

        if (H < 1e-9) {
            H = H + 360.0f;
        }
    }
    printf("%.4lf,%.4lf%%,%.4lf%%", H, S * 100, V * 100);
    return 0;
}

方阵

#include <stdio.h>

int main(){
    int n,m;
    scanf("%d",&n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            m = (i-j) > 0 ? (i-j) : (j-i);
            printf("%d  ",m);
        }
        printf("n");
    }
    return 0;
}

分数的加、减、乘、除

#include <stdio.h>

int gcd(int a,int b) {
    if (b == 0) return a;
    else return gcd(b,a%b);
}

int main() {
    int a,b,c,d;
    scanf("%d",&a);
    getchar();
    scanf("%d",&b);
    getchar();
    scanf("%d",&c);
    getchar();
    scanf("%d",&d);

    printf("(%d/%d)+(%d/%d)=%d/%dn",a,b,c,d,(a*d+b*c)/gcd(a*d+b*c,b*d),b*d/gcd(a*d+b*c,b*d));
    printf("(%d/%d)-(%d/%d)=%d/%dn",a,b,c,d,(a*d-b*c)/gcd(a*d-b*c,b*d),b*d/gcd(a*d-b*c,b*d));
    printf("(%d/%d)*(%d/%d)=%d/%dn",a,b,c,d,(a*c)/gcd(a*c,b*d),b*d/gcd(a*c,b*d));
    printf("(%d/%d)/(%d/%d)=%d/%dn",a,b,c,d,(a*d)/gcd(a*d,b*c),b*c/gcd(a*d,b*c));
    return 0;
}

操作数

#include <stdio.h>

int sumDig(int n){
    int sum = 0;
    while(n){
        sum += n%10;
        n /= 10;
    }
    return sum;
}

int main(){
    int n,cnt=0;
    scanf("%d",&n);

    while(n){
        n -= sumDig(n);
        ++cnt;
    }

    printf("%d",cnt);
    return 0;
}

比率

#include <stdio.h>
#include <math.h>

int gcd(int a,int b){
    if (b == 0) return a;
    else return gcd(b,a%b);
}

int cntDig(double x){
    int cnt = 0;
    while(x != floor(x)){
        ++cnt;
        x *= 10;
    }
    return cnt;
}

int main(){

    double x;
    scanf("%lf",&x);

    int cnt = cntDig(x), n, m, g;
    m = pow(10,cnt);
    n = (int)(x*m);
    g = gcd(m,n);
    m /= g;
    n /= g;

    printf("%d/%d",n,m);
    return 0;
}

级数和

#include <stdio.h>
#include <math.h>

double decimal (int n){
    double m = (double)n+1;
    while(floor(m)){
        m /= 10;
    }
    return m+n;
}

int main(){
    int n;
    scanf("%d",&n);
    double sum = 0.0f, term;
    for (int i = 1; i < n; ++i) {
        term = decimal(i);
        sum += term;
        printf("%g+",term);
    }
    term = decimal(n);
    sum += term;
    printf("%g=%g",term,sum);

    return 0;
}

对称数

#include <stdio.h>

int main(){
    int n;
    scanf("%d",&n);
    int a = (n/100)%10;
    int b = (n/10)%10;
    int c = n%10;

    if ((b == 0 || b == 1 || b == 8) && ((a == 6 && c == 9) || (a == 9 && c == 6)
    || ((a == 0 || a == 1 || a == 8) && (c == 0 || c == 1 || c == 8)))){
        printf("Yesn");
    } else {
        printf("Non");
    }
    return 0;
}

倍数和

#include <stdio.h>

int main(){
    unsigned int t = 0;
    scanf("%u", &t);
    unsigned int arrn[t];
    for(unsigned int i = 0; i < t; i++){
        scanf("%u", &arrn[i]);
    }

    for(unsigned int j = 0; j < t; j++){
        unsigned int res = 0;
        for(unsigned int x = 1; x < arrn[j]; x++){
            if(x % 3 == 0 || x % 5 == 0){
                res += x;
            }
        }
        printf("%un", res);
    }

    return 0;
}

最大数字

#include <stdio.h>
#include <stdbool.h>

bool isNonDecr(unsigned int n){
    unsigned int left;
    while(n){
        left = (n/10)%10;
        if (left > (n%10)){
            return false;
        }
        n /= 10;
    }
    return true;
}

int main() {
    unsigned int n, res;
    scanf("%u",&n);
    while(!isNonDecr(n)){
        --n;
    }
    printf("%u",n);
    return 0;
}

毕达哥拉斯三元组

#include <stdio.h>

unsigned long long pythagoras(unsigned int sum){
    // a as short catheti, b as long catheti, c as hypotenuse
    unsigned int a,b,c;
    for (a = 1; a <= sum/4; ++a){
        for (b = a+1; b <= sum/2; ++b){
            c = sum-a-b;
            if ((a+b > c)  && (a*a+b*b == c*c)){
                return a*b*c;
            }
        }
    }
}

int main(){
    unsigned int n;
    scanf("%u",&n);
    printf("%llu", pythagoras(n));
    return 0;
}

竖式乘法

#include <stdio.h>
#include <math.h>

typedef unsigned int uint;

uint digit(uint x){
    uint cnt = 0;
    if (x == 0){
        return 1;
    }
    while(x){
        x /= 10;
        ++cnt;
    }
    return cnt;
}

uint getDigital(uint x, uint n){
    x /= (uint)pow(10,n-1);
    return x%10;
}

int main(){
    uint up, down;
    scanf("%u %u",&up,&down);
    uint ans = up*down, len = digit(ans)+1, downLen = digit(down);

    for (uint i = 0; i < len-digit(up); ++i) {
        printf(" ");
    }
    printf("%un",up);
    printf("x");
    for (uint i = 1; i <= len-downLen-1; ++i) {
        printf(" ");
    }
    printf("%un",down);

    for (uint i = 1; i <= len; ++i) {
        printf("-");
    }
    printf("n");

    uint tmp;
    for (uint i = 1; i <= downLen; ++i) {
        tmp = getDigital(down,i)*up;
        if (i == downLen){
            printf("+");
        } else {
            for (uint j = 1; j <= len-digit(tmp)-i+1; ++j) {
                printf(" ");
            }
        }
        printf("%un",tmp);
    }

    for (uint i = 1; i <= len; ++i) {
        printf("-");
    }
    printf("n");

    printf(" %u",ans);

    return 0;
}

查找数列

#include <stdio.h>

int main(){
    int cnt = 1, sum = 0, n, res;
    scanf("%d",&n);
    while(n-sum > 0){
        sum += cnt;
        ++cnt;
    }
    sum -= cnt;
    res = n-sum == 0 ? cnt : (n-sum-1);
    printf("%d",res);
    return 0;
}

俄罗斯农夫乘法

#include <stdio.h>

int main(){
    int multi = 0, a, b;
    scanf("%d %d",&a,&b);
    while(a){
        printf("%d %dn",a,b);
        if (a&1) {
            multi += b;
        }
        a >>= 1;
        b <<= 1;
    }
    printf("%d",multi);
    return 0;
}

哈沙德数

#include <stdio.h>

int HarshadNumber(int n){
    int t = n, s = 0;
    while (t) {
        s += t%10;
        t /= 10;
    }
    if ((s == 0) || (n%s != 0)) return 0;
    if (s == 1) return 1;
    return n/s;
}

int main(){
    int cnt = 0, n;
    scanf("%d",&n);
    if (n == 1) cnt = 1;
    while ((n != 0) && (n != 1)) {
        n = HarshadNumber(n);
        if (n) ++cnt;
    }
    printf("%d",cnt);
    return 0;
}

基思数

#include <stdio.h>

int arr[8] = {0};

int init(int n){
    int cnt = 0;
    while (n) {
        arr[cnt++] = n%10;
        n /= 10;
    }
    return cnt;
}

void isKeith(int n, int len){
    int i = len - 1;
    while (arr[i] < n){
        int sum = 0;
        for (int j = 0; j < len; ++j) {
            sum += arr[(i-j+len)%len];
        }
        arr[i] = sum;
        i = (i-1+len)%len;
    }
    if (arr[i] == n) printf("Yes");
    else printf("No");
}

int main() {
    int n;
    scanf("%d",&n);
    isKeith(n,init(n));
    return 0;
}

二进制表示

#include <stdio.h>
#include <stdbool.h>

void binary(int a){
    bool flag = false;
    for (int i = 15; i >= 0 ; --i) {
        if ((a>>i)&1) {
            if (flag) printf("+");
            if (i >= 2){
                printf("2(");
                binary(i);
                printf(")");
            }
            if (i == 1) printf("2");
            if (i == 0) printf("2(0)");
            flag = true;
        }
    }
}

int main() {
    int a;
    scanf("%d",&a);
    binary(a);
    return 0;
}

冰雹数列

#include <stdio.h>

int main() {
    int n;
    scanf("%d",&n);
    while (n != 1) {
        printf("%d ",n);
        if (n&1) n = 3 * n + 1;
        else n /= 2;
    }
    printf("1");
    return 0;
}

中等题

幂数模

#include <stdio.h>

typedef unsigned long long uint64;

uint64 fastPowerMod (uint64 t, uint64 e, uint64 m){
    uint64 r = 1;
    while (e){
        if (e&1){
            r = (r*t)%m;
        }
        t = (t*t)%m;
        e >>= 1;
    }
    return r;
}

int main(){
    uint64 a,b,m,r;
    scanf("%llu %llu %llu",&a,&b,&m);
    r = fastPowerMod(a,b,m);
    printf("%llu",r);
    return 0;
}

倒水

#include <stdio.h>
#include <string.h>

#define INF 0x3f3f3f3f

const int maxSize = 10000;
int distTable[10000][10000];
int queue[10000][2] = {0};

int bfs(int n, int m, int d){
    int head = 0, tail = 1;
    memset(distTable, 0x3f, sizeof(distTable));
    distTable[0][0] = 0;

    while(tail != head){
        int a = queue[head][0], b = queue[head][1];
        if (a == d || b == d) {
            return distTable[a][b];
        }

        head = (head+1)%maxSize;

        // full
        if(distTable[a][m] == INF) {
            distTable[a][m] = distTable[a][b]+1;
            tail = (tail+1)%maxSize;
            queue[tail][0] = a;
            queue[tail][1] = m;
        }
        if(distTable[n][b] == INF) {
            distTable[n][b] = distTable[a][b]+1;
            tail = (tail+1)%maxSize;
            queue[tail][0] = n;
            queue[tail][1] = b;
        }

        // empty
        if(distTable[a][0] == INF) {
            distTable[a][0] = distTable[a][b]+1;
            tail = (tail+1)%maxSize;
            queue[tail][0] = a;
            queue[tail][1] = 0;
        }
        if(distTable[0][b] == INF) {
            distTable[0][b] = distTable[a][b]+1;
            tail = (tail+1)%maxSize;
            queue[tail][0] = 0;
            queue[tail][1] = b;
        }

        // pour
        if(a+b < n && distTable[a+b][0] == INF){
            distTable[a+b][0] = distTable[a][b]+1;
            tail = (tail+1)%maxSize;
            queue[tail][0] = a+b;
            queue[tail][1] = 0;
        }
        if(a+b >= n && distTable[n][a+b-n] == INF){
            distTable[n][a+b-n] = distTable[a][b]+1;
            tail = (tail+1)%maxSize;
            queue[tail][0] = n;
            queue[tail][1] = a+b-n;
        }
        if(a+b < m && distTable[0][a+b] == INF){
            distTable[0][a+b] = distTable[a][b]+1;
            tail = (tail+1)%maxSize;
            queue[tail][0] = 0;
            queue[tail][1] = a+b;
        }
        if(a+b >= m && distTable[a+b-m][m] == INF){
            distTable[a+b-m][m] = distTable[a][b]+1;
            tail = (tail+1)%maxSize;
            queue[tail][0] = a+b-m;
            queue[tail][1] = m;
        }
    }
    return -1;
}

int main(){
    int n,m,d;
    scanf("%d %d %d",&n,&m,&d);
    printf("%d", bfs(n,m,d));
    return 0;
}

好数字

#include <stdio.h>

typedef unsigned long long uint64;
const uint64 mod = 1e9+7;

uint64 power(uint64 a, uint64 e){
    uint64 r = 1;
    while (e){
        if (e&1){
            r = (r*a)%mod;
        }
        a = (a*a)%mod;
        e >>= 1;
    }
    return r;
}

int main(){
    uint64 n, num;
    scanf("%llu",&n);
    num = power(4,n/2)*power(5,n-n/2)%mod;
    printf("%llu",num);
    return 0;
}

阶乘倍数

#include <stdio.h>
#include <stdbool.h>
 
typedef unsigned long long uint64;

uint64 primeFactNum = 0;
uint64 prime[20] = {0}, num[20] = {0};

bool isMulti(uint64 n){
    uint64 primeNum, tmp;
    for (uint64 i = 1; i <= primeFactNum; ++i) {
        primeNum = 0;
        tmp = n;
        while (tmp) {
            primeNum += tmp/prime[i];
            tmp /= prime[i];
        }
        if(primeNum < num[i]) {
            return false;
        }
    }
    return true;
}

void solveFact(uint64 k){
    for (uint64 i = 2; i*i <= k; ++i) {
        if(k%i == 0){
            ++primeFactNum;
            prime[primeFactNum] = i;
            while (k%i == 0){
                ++num[primeFactNum];
                k /= i;
            }
        }
    }
    if (k > 1){
        ++primeFactNum;
        prime[primeFactNum] = k;
        ++num[primeFactNum];
    }
}
 
int main(){
    uint64 left = 1, right = 1e19, mid, n, k;
    scanf("%lld",&k);
    solveFact(k);
 
    while(left <= right){
        mid = ((right-left)>>1)+left;
        if (isMulti(mid)){
            right = mid-1;
            n = mid;
        } else {
            left = mid+1;
        }
    }
    printf("%lld",n);
    return 0;
}

方案数

#include <stdio.h>

int main(){
    int cnt = 0, n;
    scanf("%d",&n);
    for (int i = 1; i*(i+1) <= 2*n; ++i) {
        if ((n-i*(i-1)/2)%i == 0){
            ++cnt;
        }
    }
    printf("%d",cnt);
    return 0;
}

素数

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

typedef unsigned long long uint64;

uint64 primeNum(uint64 a, uint64 b){
    bool isPrime[b+1];
    memset(isPrime,1,b+1);
    uint64 cnt = 0;
    for (uint64 i = 2; i <= b; ++i){
        if (isPrime[i]){
            for (uint64 j = 2; j*i <= b; ++j){
                isPrime[j*i] = false;
            }
        }
    }
    for (uint64 i = a; i <= b; ++i){
        cnt += isPrime[i];
    }
    return cnt;
}

int main(){
    uint64 a,b,num;
    scanf("%llu %llu",&a,&b);
    num = primeNum(a,b);
    printf("%llu",num);
    return 0;
}

光线追踪

#include <stdio.h>

unsigned int gcd(unsigned int a, unsigned int b){
    if (b == 0) return a;
    return gcd(b,a%b);
}

int main(){
    unsigned int n,x,l;
    scanf("%u %u",&n,&x);
    l = 3*(n-gcd(n,x));
    printf("%u",l);
    return 0;
}

运动会

#include <stdio.h>
#include <stdbool.h>

int phiEuler(int n){
    int phi[n+1],prime[n+1];
    bool isSieved[n+1];
    int sum = 0,cnt = 1, comp;
    prime[0] = 1;
    phi[1] = 1;
    for (int i = 2; i < n; ++i){
        if (!isSieved[i]){
            prime[cnt++] = i;
            phi[i] = i-1;
        }
        for (int j = 1; i*prime[j] <= n; ++j){
            comp = i*prime[j];
            isSieved[comp] = true;
            if (i%prime[j] == 0){
                phi[comp] = prime[j]*phi[i];
                break;
            } else{
                phi[comp] = (prime[j]-1)*phi[i];
            }
        }
    }
    for (int i = 1; i <= n-1; ++i) {
        sum += phi[i];
    }
    return sum;
}

int main() {
    int n, num;
    scanf("%d",&n);
    num = n == 1 ? 0 : (2*phiEuler(n)+1);
    printf("%d",num);
    return 0;
}