/*
gesp3必会代码、编程思想 v1.0.3 
zycsuper 2026/3/15
*/

/* 2026/2/5
p:往数组中增加元素
s:定义数组索引变量i,让i自增,赋值以i为下标的数组元素
c:
#include <bits/stdc++.h>
using namespace std;
int main() {
    char s[5];
    int i=0;
    s[i]='A';
    i++;
    s[i]='B';
    cout<<s;
} */

/*
p:十进制转换为二进制
s:模拟除法过程,余数倒数输出(假设堆栈没有学习)
c:
#include <bits/stdc++.h>
using namespace std;
string DectoBin(int n) {
    if (n == 0) return "0"; // 处理0的特殊情况
    string s="";
    while (n > 0) {
        s += (n % 2) + '0'; // 尾部追加,不要用insert,效率低
        n /= 2;
    }
    reverse(s.begin(), s.end()); // 反转字符串(O(n))
    return s;
}
int main() {
    int n=19;
    cout<<DectoBin(n);
    return 0;
}*/

/*
p:十进制N转换为R进制
s:模拟R进制除法过程,余数倒数输出,堆栈更方便
c:
#include <iostream>
#include <stack>
using namespace std;
int main() {
    int N,R;
    cin>>N>>R;
    stack<int> sk;
    while (N>0) { //对应图解:求余数、商
        int y=N%R;
        sk.push(y);
        N/=R;
    }
    while (!sk.empty()) { //输出余数
        int t=sk.top();
        cout<<t;
        sk.pop();
    }
    return 0;
}*/

/*
p:统计很多特征的值
s:把特征编号,作为数组的下标
c:
#include <bits/stdc++.h>
using namespace std;
int t[100]={0};    //统计数组
int main() {
    int k=2;   //特征编号,1~n
    t[k]++;    //统计k的数量,以后用map实现:词频统计
    cout<<t[k];
    return 0;
}*/

/*
p:判断某个整数是几进制的数
s:找出其中最大的数,小于R就是R进制
c:
#include <bits/stdc++.h>
using namespace std;
int main() {
   string s="15A6F";
   char max = '0';
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] > max) max = s[i];
    }
    cout << (max <= '1') << " " << (max <= '7') << " " << (max <= '9') << " " << 
          (max <= 'F') << endl;
    return 0;
} */

/*
p:一行输出多个空格隔开的数据
s:虽然cout也能实现,但是printf更方便
  常见格式:%d 整数
           %c 字符
           %.2lf 保留2位小数
           %s 字符串
c:
#include <bits/stdc++.h>
using namespace std;
int main() {
    int a=10;
    char s[10]="hello";
    int b=20;
    char t[20]="world";
    printf("%d %s = %d %s\n", a, s, b, t); //10 hello = 20 world
    return 0;
} */

/*
p:回文数判断方法一:倒序比较法
s:倒序输出字符串,比较值
c:
#include <bits/stdc++.h>
using namespace std;
bool isHW(string s) { //判断一个回文串 
	string rs="";     //倒转的字符
	for (int i=s.length()-1;i>=0;i--) { //string知识需要
		rs.push_back(s[i]);
	}
	if (rs==s) return true;
	else return false;   //可精简为:return rs==s;
}
int main() {
    string s;  //12321
    cin>>s;
    if (isHW(s)) cout<<"yes";
    else cout<<"no";
    return 0;
}*/

/*
p:回文数判断方法二:对称比较法
s:遍历一半,对称比较字符,显然这个最快
c
#include <bits/stdc++.h>
using namespace std;
bool isHW(string s) { //判断一个回文串
    int n=s.length();
	for (int i=0;i<n/2;i++) { //遍历一半
        if (s[i]!=s[n-i-1])   //i 对应 n-i-1
            return false;
    }
    return true;
}
int main() {
    string s="123321";  //12321
    cout<<isHW(s);
    return 0;
} */


/*
p:n个元素,两两组合枚举
s:两层循环,外层i从1~n-1,内层i+1~n
c:
#include <bits/stdc++.h>
using namespace std;
int a[5]={1,2,3,4,5};
int main() {
    int n=5;
    for (int i=0;i<n-1;i++) {     //下标从0,所以<n-1
        for (int j=i+1;j<n;j++) { //i+1,不重复前面组合
            cout<<i<<' '<<j<<endl;
        }
    }
    return 0;
} */

/*
p:处理字符串方法一
s:使用字符数组
c:参见字符数组代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    char a[16];   
    scanf("%[^\n]",a); //读取一行空格分开的字符串
                       //[]中是正则表达式,不会车就读取
    printf("%s",a);
    return 0;
} */

/* 2026/3/15
p:判断完数。
  一个数如果恰好等于它的真因子(不包括自身)之和,则称该数为完数
s:遍历数字相除判断因子,注意去重
c:*/
#include <bits/stdc++.h>
using namespace std;

int main() {
    long long n;
    cin >> n;
    if (n < 2) { // 处理特殊情况:小于2的数不可能是完数
        cout << "NO" << endl;
        return 0;
    }
    long long sum = 1; // 1是所有大于1的数的真约数,先计入
    for (long long i = 2; i * i <= n; ++i) { // 遍历到sqrt(n)即可,减少循环次数(约数成对出现)
        if (n % i == 0) {
            sum += i; // 加入小的约数
            if (i != n / i) { // 避免平方数重复加(比如4的约数2,只加一次)
                sum += n / i;
            }
        }
    }
    if (sum == n) { // 判断是否等于自身
        cout << "YES" << endl;
    } else {
        cout << "NO" << endl;
    }
    return 0;
}

/*
p:处理字符串方法二
s:使用string类
c:参见string代码
*/

/*
编程思想:计算思维
0、编码习惯:分析 -> 伪代码 -> 代码,案例:202412月题:数字替换
1、标记变量:某种状态的标记,bool或者int,不同标记做不同处理
2、函数分解:代码嵌套复杂时,分解为函数,通过函数调用实现结构清晰,例如:奇偶校验
*/