完全数
- 完全数满足:一个数的所有因子之和 - 它自己 = 它自己
- 因子之和 = 约数之和
- 求一个数的所有约数之和:
先把每个质因数从0次幂一直加到其最高次幂,再把每个相应质因数幂的和相乘.
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define mm(a,x) memset(a,x,sizeof a)
#define mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)
#define endl "\n"
ll n;
unordered_map<int,int > primes;
ll ans = 1;
void divide(ll n){
for(ll i = 2; i <= n/i; i ++ ){
while(n % i == 0){
n/=i;
primes[i] ++;
}
}
if(n > 1) primes[n] ++;
}
int main() {
cin >> n;
divide(n);
for(auto prime:primes){
ll p = prime.first,a = prime.second;
ll t = 1;
while(a -- ) t = t * p + 1;
ans *= t;
}
if(ans - n == n) cout<<"Pure";
else if(ans - n > n) cout<<"Late";
else cout<<"Early";
return 0;
}移动撤销
- 利用栈来存放上一次操作
- 若栈不为空,就可以撤销
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define mm(a,x) memset(a,x,sizeof a)
#define mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)
#define endl "\n"
const int N = 1e5 + 10;
int n;
string s;
int x,y;
int stk[N],tt;
int main() {
cin >> n >> s;
int len = s.size();
for(int i = 0; i < len; i ++ ){
if(s[i] == 'W') y ++,stk[++ tt] = 1;
if(s[i] == 'A') x --,stk[++ tt] = 2;
if(s[i] == 'S') y --,stk[++ tt] = 3;
if(s[i] == 'D') x ++,stk[++ tt] = 4;
if(s[i] == 'Z'){
int t = 0;
if(tt) t = stk[tt --];
if(t == 1) y --;
if(t == 2) x ++;
if(t == 3) y ++;
if(t == 4) x --;
}
}
cout<<x<<" "<<y;
return 0;
}石头剪刀布
贪心策略:先把所有可能胜出的情况进行枚举,然后考虑平局的情况
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define mm(a,x) memset(a,x,sizeof a)
#define mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)
#define endl "\n"
const int N = 10;
int n;
ll a[N],b[N];
ll ans;
//每局胜者得2分,平局双方各得1分,败者不得分
int main() {
cin >> n;
for(int i = 0; i < 3; i ++ ){
cin >> a[i];
}
for(int i = 0; i < 3; i ++ ){
cin >> b[i];
}
ll x = 0;
x = min(a[0],b[1]);
ans += x * 2;
a[0] -= x;
b[1] -= x;
x = min(a[1],b[2]);
ans += x * 2;
a[1] -= x;
b[2] -= x;
x = min(a[2],b[0]);
ans += x * 2;
a[2] -= x;
b[0] -= x;
ans += min(a[0],b[0]);
ans += min(a[1],b[1]);
ans += min(a[2],b[2]);
cout<<ans;
return 0;
}夹缝中求和
- n的范围在[2,1e5],时间复杂度O(n)或者O(nlogn)
- 选取一个数ai,另一个数一定在[x - ai,y - ai]之间
- 先进行排序,再进行二分查找不小于当前值作为左端点l,大于当前值作为右端点r
- 符合答案的区间为r - l.
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define mm(a,x) memset(a,x,sizeof a)
#define mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)
#define endl "\n"
const int N = 1e5 + 10;
ll n,x,y;
ll a[N];
int l,r;
ll ans;
int main() {
cin >> n >> x >> y;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
sort(a + 1, a + n + 1);
for(int i = 1; i <= n; i ++ ){
l = lower_bound(a + i + 1,a + n + 1,x - a[i]) - a;
r = upper_bound(a + i + 1,a + n + 1,y - a[i]) - a;
ans += (r - l);
}
cout<<ans;
return 0;
}


京公网安备 11010502036488号