#include<bits/stdc++.h>
using namespace std;int n, t, a[100]={0,1};intmain(){// freopen("hanoi.in", "r", stdin);// freopen("hanoi.out", "w", stdout);
cin >> n;//t表示进位 for(int i =1; i <= n +1; i ++){
t =0;for(int j =1; j <=61; j ++){
t += a[j]*2;
a[j]= t %10;
t /=10;}}//t表示借位
t =2;for(int i =1; i <=61; i ++){
t = a[i]- t;if(t <0) t =1, a[i]= t +10;else{
a[i]= t;break;}}//去掉前导0 for(int i =61; i >=1; i --){if(a[i]!=0){
t = i;break;}}for(int i = t; i >=1; i --) cout << a[i];return0;}
#include<bits/stdc++.h>
using namespace std;int p, k, ans[510]={1}, len =1;intmain(){// freopen("mason.in", "r", stdin);// freopen("mason.out", "w", stdout);
cin >> p;
k = p *log10(2)+1;
cout << k << endl;for(int i =1; i <= p; i ++){int t =0;for(int j =0; j <500; j ++){
t += ans[j]*2;
ans[j]= t %10;
t = t /10;}}
ans[0]-=1;for(int i =499; i >=0; i --){
cout << ans[i];if(i %50==0) cout << endl;}return0;}
#include<bits/stdc++.h>
using namespace std;constint N =510;int p, k;int base[N], ans[N], tmp[N];//a * b -> cvoidmul(int a[],int b[],int c[]){memset(tmp,0,sizeof(tmp));for(int i =0; i <500; i ++){for(int j =0; j <500; j ++){if(i + j <500){
tmp[i + j]+= a[i]* b[j];}}}int t =0;for(int i =0; i <500; i ++){
t += tmp[i];
c[i]= t %10;
t = t /10;}}intmain(){// freopen("mason.in", "r", stdin);// freopen("mason.out", "w", stdout);
cin >> p;
k = p *log10(2)+1;
cout << k << endl;
ans[0]=1;
base[0]=2;while(p){if(p &1)mul(ans, base, ans);mul(base, base, base);
p >>=1;}
ans[0]-=1;for(int i =499; i >=0; i --){
cout << ans[i];if(i %50==0) cout << endl;}return0;}
二分
2015年提高组D2T1 跳石头
#include<bits/stdc++.h>
using namespace std;constint N =5e4+10;int len, n, m;int d[N];//返回当最短跳跃距离是x时,应该移走的岩石数量 intcheck(int x){int res =0, pos =0;//起点 for(int i =1; i <= n; i ++){if(d[i]- pos < x) res ++;else pos = d[i];}return res;}intmain(){// freopen("stone.in", "r", stdin);// freopen("stone.out", "w", stdout);scanf("%d%d%d",&len,&n,&m);for(int i =1; i <= n; i ++)scanf("%d",&d[i]);
d[++ n]= len;int l =0, r = len, ans;while(l <= r){int mid = l + r >>1;if(check(mid)<= m){
ans = mid;
l = mid +1;}else{
r = mid -1;}}printf("%d\n", ans);return0;}
贪心,优先队列优化
2004年普及组T2 花生采摘
#include<bits/stdc++.h>
using namespace std;constint N =30;int m, n, k, t, cnt;structnode{int x, y, num;};
bool operator <(node x, node y){return x.num < y.num;}
priority_queue <node, vector<node>, less<node>> q;intmain(){// freopen("mason.in", "r", stdin);// freopen("mason.out", "w", stdout);
cin >> m >> n >> k;for(int i =1; i <= m; i ++){for(int j =1; j <= n; j ++){int p;
cin >> p;
node t ={i, j, p};
q.push(t);//优先队列堆顶的花生数量最多}}
node pre, now;for(int i =1;; i ++){
now = q.top();if(i ==1) pre ={0, now.y,0};//从第0行第now.y列出发
t +=abs(now.x - pre.x)+abs(now.y - pre.y)+1;//曼哈顿距离 + 采摘时间 if(t + now.x <= k) cnt += now.num;//如果来得及回去就采 elsebreak;//否则就回去
pre = now;
q.pop();if(q.empty())break;//采完了就回去 }
cout << cnt << endl;return0;}
2015年普及组T4 推销员
#include<iostream>#include<cstdio>#include<queue>
using namespace std;constint N =1e5+10;int n, s[N], a[N], t[N], h[N];//路程,疲劳值,total, 往右找 t 值最高的人家的编号
priority_queue < pair<int,int>> q;//first:疲劳值,second:i intmain(){scanf("%d",&n);for(int i =1; i <= n; i ++)scanf("%d",&s[i]);for(int i =1; i <= n; i ++){scanf("%d",&a[i]);
t[i]= a[i]+2* s[i];}int k = n;for(int i = n -1; i >=0; i --){
h[i]= k;//第 i 户人家右侧 t 值最高的人家的编号是 h[i] if(t[i]> t[k]) k = i;}int ans =0;//已经推销了x-1户人家,总疲劳值为 ansint lst =0;//已经推销过的人家中最远的一家 int l, r;for(int x =1; x <= n; x ++){if(q.size()) l = q.top().second;//第 x 户人家左侧未推销的人家中疲劳值最大的人家的编号
r = h[lst];if(q.size()&& a[l]< a[r]+2*(s[r]- s[lst])||!q.size()){
ans += a[r]+2*(s[r]- s[lst]);//去编号为 r 的人家推销 for(int i = lst +1; i < r; i ++){//将左侧的人家加入优先队列
q.push({a[i], i});}
lst = r;}else{//去编号为 l 的人家推销
ans += a[l];
q.pop();}printf("%d\n", ans);}return0;}
枚举
2015年普及组T3 求和
枚举,70分
#include<iostream>#include<cstdio>#include<vector>
using namespace std;constint N =1e5+10, M =1e5+10;int n, m, num[N];
vector <int> col[M];//有m种颜色,第 i种颜色的数量为 col[i].size() intmain(){scanf("%d%d",&n,&m);for(int i =1; i <= n; i ++)scanf("%d",&num[i]);for(int i =1; i <= n; i ++){int c;scanf("%d",&c);//某种颜色
col[c].push_back(i);//将每个格子的编号存储到对应颜色的数组里 }//编号之和 * 数字之和有可能大于 MAX_INT longlong ans =0;for(int i =1; i <= m; i ++){//枚举第 i 种颜色 for(int j =0; j < col[i].size(); j ++){//枚举编号为 x的格子for(int k = j +1; k < col[i].size(); k ++){//枚举编号为 y的格子int x = col[i][j];int z = col[i][k];if(x %2== z %2){
ans +=(longlong)(x + z)*(num[x]+ num[z]);
ans %=10007;}}}}printf("%lld\n", ans);return0;}
2016年普及组T4 魔法阵
枚举,60分
#include<iostream>#include<cstdio>#include<cstring>
using namespace std;constint N =15010, M =40010;int n, m;int x[M], ans[M][5];intmain(){scanf("%d %d",&n,&m);for(int i =1; i <= m; i ++){int a;scanf("%d",&x[i]);}for(int a =1; a <= m; a ++){for(int b =1; b <= m; b ++){if(x[b]<= x[a])continue;for(int c =1; c <= m; c ++){if(x[c]<= x[b])continue;if((x[b]- x[a])%2==1)continue;if(3*(x[b]- x[a])>=(x[c]- x[b]))continue;for(int d =1; d <= m; d ++){if(x[b]- x[a]==2*(x[d]- x[c])){
ans[a][1]++;
ans[b][2]++;
ans[c][3]++;
ans[d][4]++;}}}}}for(int i =1; i <= m; i ++){for(int j =1; j <=4; j ++){printf("%d ", ans[i][j]);}printf("\n");}return0;}