版本:1.0.0.0.3
最后更新时间:2020-7-8 20:23:43
字数:15456
扫码手机看!
P1000 超级玛丽游戏
P1001 A+B Problem
P1116 车厢重组
P1789 【Mc生存】插火把
P5718 【深基4.例2】找最小值
P5737 【深基7.例3】闰年展示
直接来吧,不需要解释代码了
#include // 万能头
using namespace std;
int main()
{
cout<<" ********"<
正常算法:
#include
using namespace std;
int main()
{
int a,b;
cin>>a>>b; //输入
cout<
与此同时,很多巨佬也用高级算法PK A+B问题。
下面展示一下:
BFS大法闪亮登场!
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int oo_min=0xcfcfcfcf,oo_max=0x3f3f3f3f;
int n,m,t;
vector f;
vector e;
vector u;
vector pre;
vector vis;
vector > c;
vector > p;
vector > ce;
vector > cw;
deque q;
void add_edge_1(int x,int y,int c_v,int p_v)
{
cw[x].push_back(y);
c[x].push_back(c_v);
p[x].push_back(p_v);
ce[y].push_back(cw[x].size()-1);
cw[y].push_back(x);
c[y].push_back(0);
p[y].push_back(-p_v);
ce[x].push_back(cw[y].size()-1);
}
int bfs_1(int s,int t,int *flow,int *cost)
{
f.resize(0);
f.resize(cw.size(),0);
f[s]=oo_max;
e.resize(0);
e.resize(cw.size(),-1);
u.resize(0);
u.resize(cw.size(),oo_max);
u[s]=0;
pre.resize(0);
pre.resize(cw.size(),-1);
pre[s]=s;
vis.resize(0);
vis.resize(cw.size(),0);
for (q.resize(0),vis[s]=1,q.push_back(s);(!q.empty());vis[q.front()]=0,q.pop_front())
{
int now=q.front();
for (int i=0;i
Dijkstra求最短路
#include
using namespace std;
const int N=405;
struct Edge {
int v,w;
};
vector edge[N*N];
int n;
int dis[N*N];
bool vis[N*N];
struct cmp {
bool operator()(int a,int b) {
return dis[a]>dis[b];
}
};
int Dijkstra(int start,int end)
{
priority_queue,cmp> dijQue;
memset(dis,-1,sizeof(dis));
memset(vis,0,sizeof(vis));
dijQue.push(start);
dis[start]=0;
while(!dijQue.empty()) {
int u=dijQue.top();
dijQue.pop();
vis[u]=0;
if(u==end)
break;
for(int i=0;idis[u]+edge[u][i].w) {
dis[v]=dis[u]+edge[u][i].w;
if(!vis[v]) {
vis[v]=true;
dijQue.push(v);
}
}
}
}
return dis[end];
}
int main()
{
int a,b;
scanf("%d%d",&a,&b);
Edge Qpush;
Qpush.v=1;
Qpush.w=a;
edge[0].push_back(Qpush);
Qpush.v=2;
Qpush.w=b;
edge[1].push_back(Qpush);
printf("%d",Dijkstra(0,2));
return 0;
}
Floyd算法
#include
using namespace std;
long long n=3,a,b,dis[4][4];
int main()
{
cin>>a>>b;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j]=2147483647;
dis[1][2]=a,dis[2][3]=b;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
cout<
LCT
#include
using namespace std;
struct node
{
int data,rev,sum;
node *son[2],*pre;
bool judge();
bool isroot();
void pushdown();
void update();
void setson(node *child,int lr);
}lct[233];
int top,a,b;
node *getnew(int x)
{
node *now=lct+ ++top;
now->data=x;
now->pre=now->son[1]=now->son[0]=lct;
now->sum=0;
now->rev=0;
return now;
}
bool node::judge()
{
return pre->son[1]==this;
}
bool node::isroot()
{
if(pre==lct)return true;
return !(pre->son[1]==this||pre->son[0]==this);
}
void node::pushdown()
{
if(this==lct||!rev)return;
swap(son[0],son[1]);
son[0]->rev^=1;
son[1]->rev^=1;
rev=0;
}
void node::update()
{
sum=son[1]->sum+son[0]->sum+data;
}
void node::setson(node *child,int lr)
{
this->pushdown();
child->pre=this;
son[lr]=child;
this->update();
}
void rotate(node *now)
{
node *father=now->pre,*grandfa=father->pre;
if(!father->isroot()) grandfa->pushdown();
father->pushdown();
now->pushdown();
int lr=now->judge();
father->setson(now->son[lr^1],lr);
if(father->isroot()) now->pre=grandfa;
else grandfa->setson(now,father->judge());
now->setson(father,lr^1);
father->update();
now->update();
if(grandfa!=lct) grandfa->update();
}
void splay(node *now)
{
if(now->isroot())return;
for(; !now->isroot(); rotate(now))
if(!now->pre->isroot())
now->judge()==now->pre->judge()?rotate(now->pre):rotate(now);
}
node *access(node *now)
{
node *last=lct;
for(; now!=lct; last=now,now=now->pre) {
splay(now);
now->setson(last,1);
}
return last;
}
void changeroot(node *now)
{
access(now)->rev^=1;
splay(now);
}
void connect(node *x,node *y)
{
changeroot(x);
x->pre=y;
access(x);
}
void cut(node *x,node *y)
{
changeroot(x);
access(y);
splay(x);
x->pushdown();
x->son[1]=y->pre=lct;
x->update();
}
int query(node *x,node *y)
{
changeroot(x);
node *now=access(y);
return now->sum;
}
int main()
{
scanf("%d%d",&a,&b);
node *A=getnew(a);
node *B=getnew(b);
connect(A,B);
cut(A,B);
connect(A,B);
printf("%d",query(A,B));
return 0;
}
main自递归和位运算
#include
int main(int a,int b,int k)
{
if(k)scanf("%d%d",&a,&b);
printf("%d",b==0?a:main(a^b,(a&b)<<1,0));
exit(0);
}
SPFA
#include
using namespace std;
int n,m,a,b,op,l,r,u,v1,e;
int head[200009],ne_xt[200009],dis[200009];
int len[200009],v[200009],team[200009],pd[100009];
int lt(int x,int y,int z)
{
op++;
v[op]=y;
ne_xt[op]=head[x];
head[x]=op;
len[op]=z;
}
int SPFA(int s,int f)
{
for(int i=1;i<=200009;i++){dis[i]=999999999;}
l=0,r=1,team[1]=s,pd[s]=1,dis[s]=0;
while(l!=r){
l=(l+1)%90000,u=team[l],pd[u]=0,e=head[u];
while(e!=0){
v1=v[e];
if(dis[v1]>dis[u]+len[e]){
dis[v1]=dis[u]+len[e];
if(!pd[v1]){
r=(r+1)%90000,
team[r]=v1,
pd[v1]=1;
}
}
e=ne_xt[e];
}
}
return dis[f];
}
int main()
{
scanf("%d%d",&a,&b);
lt(1,2,a);
lt(2,3,b);
printf("%d",SPFA(1,3));
return 0;
}
普通递归法
#include
using namespace std;
long long a,b,c;
long long dg(long long a)
{
if(a<=5)return a;
return (dg(a/2)+dg(a-a/2));
}
int main()
{
cin>>a>>b;
cout<
二分法
#include
using namespace std;
long long a,b,c;
long long dg(long long a)
{
if(a<=5)return a;
return (dg(a/2)+dg(a-a/2));
}
int main()
{
cin>>a>>b;
cout<
普通高精度
#include
using namespace std;
char a1[1000],b1[1000];
int a[1000],b[1000],c[1000],la,lb,lc=1,i,x;
int main()
{
cin>>a1>>b1;
la=strlen(a1);
lb=strlen(b1);
for(i=0;i<=la-1;i++)a[la-i]=a1[i]-'0';
for(i=0;i<=lb-1;i++)b[lb-i]=b1[i]-'0';
while(lc<=la||lc<=lb){c[lc]=a[lc]+b[lc]+x,x=c[lc]/10,c[lc]%=10,lc++;}
c[lc]=x;
if(c[lc]==0)lc--;
for(i=lc;i>=1;i--)cout<
压位高精
#include
#define p 8
#define carry 100000000
using namespace std;
const int Maxn=50001;
char s1[Maxn],s2[Maxn];
int a[Maxn],b[Maxn],ans[Maxn];
int change(char s[],int n[])
{
char temp[Maxn];
int len=strlen(s+1),cur=0;
while(len/p){
strncpy(temp,s+len-p+1,p);
n[++cur]=atoi(temp);
len-=p;
}
if(len){
memset(temp,0,sizeof(temp));
strncpy(temp,s+1,len);
n[++cur]=atoi(temp);
}
return cur;
}
int add(int a[],int b[],int c[],int l1,int l2)
{
int x=0,l3=max(l1,l2);
for(int i=1;i<=l3;i++){
c[i]=a[i]+b[i]+x;
x=c[i]/carry;
c[i]%=carry;
}
while(x>0){c[++l3]=x%10;x/=10;}
return l3;
}
void print(int a[],int len)
{
printf("%d",a[len]);
for(int i=len-1;i>=1;i--)printf("%0*d",p,a[i]);
printf("\n");
}
int main()
{
scanf("%s%s",s1+1,s2+1);
int la=change(s1,a);
int lb=change(s2,b);
int len=add(a,b,ans,la,lb);
print(ans,len);
}
网络流
#include
using namespace std;
#define set(x) Set(x)
#define REP(i,j,k) for (int i=(j),_end_=(k);i<=_end_;++i)
#define DREP(i,j,k) for (int i=(j),_start_=(k);i>=_start_;--i)
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()-1))
#define ALL(x) ((x).begin()+1),(x).end()
template inline bool chkmin(T &a,const T &b){ return a > b ? a = b, 1 : 0; }
template inline bool chkmax(T &a,const T &b){ return a < b ? a = b, 1 : 0; }
typedef long long LL;
typedef pair node;
const int dmax=1010,oo=0x3f3f3f3f;
int n,m;
int a[dmax][dmax] , ans;
int d[dmax],e[dmax];
priority_queue q;
inline bool operator >(node a,node b){ return a.y>b.y; }
bool p[dmax];
void Set(int x){ p[x]=1; }
void unset(int x){ p[x]=0; }
bool check(int x){ return x!=1 && x!=n && !p[x] && e[x]>0; }
void preflow(){
e[1]=oo;
d[1]=n-1;
q.push(mp(1,n-1));
set(1);
while (!q.empty()){
bool flag=1;
int k=q.top().x;
q.pop(),unset(k);
DREP(i,n,1)
if ((d[k]==d[i]+1 || k==1) && a[k][i]>0){
flag=0;
int t=min(a[k][i],e[k]);
e[k]-=t;
a[k][i]-=t;
e[i]+=t;
a[i][k]+=t;
if (check(i)){
q.push(mp(i,d[i]));
set(i);
}
if (e[k]==0) break;
}
if (flag){
d[k]=oo;
REP(i,1,n)
if (a[k][i]>0)chkmin(d[k],d[i]+1);
}
if (check(k)){
q.push(mp(k,d[k]));
set(k);
}
}
ans=e[n];
}
int main(){
n = 2, m = 2;
int x, y;
scanf("%d%d", &x, &y);
a[1][2] += x + y;
preflow();
printf("%d\n",ans);
return 0;
}
线段树
#include
using namespace std;
const int MAXN = 5000 + 10;
struct Tree
{
int l, r, val;
}t[MAXN * 4];
int N = 2, a[MAXN];
inline void init()
{
for(int i=1; i<=N; i++)
scanf("%d", &a[i]);
}
void Build(int Root, int L, int R)
{
t[Root].l = L;
t[Root].r = R;
t[Root].val = 0;
if(L == R) {
t[Root].val = a[L];
return ;
}
int m = (L + R) >> 1;
int Next = Root * 2;
Build(Next, L, m);
Build(Next+1, m+1, R);
t[Root].val = t[Next].val + t[Next+1].val;
}
void Updata(int Root, int pos, int _val)
{
if(t[Root].l == t[Root].r) {
t[Root].val += _val;
return ;
}
int Next = Root * 2;
int m = (t[Root].l + t[Root].r) >> 1;
if(pos <= m) Updata(Next, pos, _val);
else Updata(Next+1, pos, _val);
t[Root].val = t[Next].val + t[Next+1].val;
}
int Doit(int Root, int L, int R)
{
if(t[Root].l>=L && t[Root].r<=R)return t[Root].val;
int Ans = 0;
int Next = Root * 2;
int m=(t[Root].l + t[Root].r) >> 1;
if(L<=m)Ans+=Doit(Next,L,R);
if(R>m)Ans+=Doit(Next+1,L,R);
return Ans;
}
int main()
{
init();
Build(1,1,N);
int Ans=Doit(1,1,N);
printf("%d", Ans);
return 0;
}
最小生成树
#include
#include
#define INF 2140000000
using namespace std;
struct tree{int x,y,t;}a[10];
bool cmp(const tree&a,const tree&b)
{
return a.t
树状数组
#include
#include
using namespace std;
int lowbit(int a)
{
return a&(-a);
}
int main()
{
int n=2,m=1;
int ans[m+1];
int a[n+1],c[n+1],s[n+1];
int o=0;
memset(c,0,sizeof(c));
s[0]=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
c[i]=s[i]-s[i-lowbit(i)];//树状数组创建前缀和优化
}
for(int i=1;i<=m;i++)
{
int q=2;
//if(q==1)
//{(没有更改操作)
// int x,y;
// cin>>x>>y;
// int j=x;
// while(j<=n)
// {
// c[j]+=y;
// j+=lowbit(j);
// }
//}
//else
{
int x=1,y=2;//求a[1]+a[2]的和
int s1=0,s2=0,p=x-1;
while(p>0)
{
s1+=c[p];
p-=lowbit(p);//树状数组求和操作,用两个前缀和相减得到区间和
}
p=y;
while(p>0)
{
s2+=c[p];
p-=lowbit(p);
}
o++;
ans[o]=s2-s1;//存储答案
}
}
for(int i=1;i<=o;i++)
cout<
一看就是冒泡排序的板子啊!
先来一段冒泡排序
用这个网站可以模拟一遍冒泡排序的全过程
网站:visualgo.net
排序快捷方式:中文版 英文版
C++代码看一下 冒泡排序:
#include
using namespace std;
template
//整数或浮点数皆可使用
void bubble_sort(T arr[], int len)
{
int i, j; T temp;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
int main()
{
int arr[] = { 61, 17, 29, 22, 34, 60, 72, 21, 50, 1, 62 };
int len = (int) sizeof(arr) / sizeof(*arr);
bubble_sort(arr, len);
for (int i = 0; i < len; i++)
cout << arr[i] << ' ';
cout << endl;
float arrf[] = { 17.5, 19.1, 0.6, 1.9, 10.5, 12.4, 3.8, 19.7, 1.5, 25.4, 28.6, 4.4, 23.8, 5.4 };
len = (int) sizeof(arrf) / sizeof(*arrf);
bubble_sort(arrf, len);
for (int i = 0; i < len; i++)
cout << arrf[i] << ' ';
return 0;
}
所以吗,在交换那里加一个计数器,比如就s
吧
记得使用前清零
完美!
#include
#include\\调用swap函数
using namespace std;
long n,i,j,t,s,a[10000];\\定义
int main()\\主函数main
{
cin>>n;\\输入n
for(i=1;i<=n;i++)
cin>>a[i];\\输入n个车厢号
for(i=1;i<=n-1;i++)\\冒泡排序另一种写法
for(j=1;j<=n-i;j++)
if(a[j]>a[j+1])\\如果a[j]>a[j+1],车厢号为逆序
{
swap(a[j],a[j+1]);\\将a[j],a[j+1]对换(ps:swap是一个对调两个变量的函数)
s++;\\统计车厢旋转的次数
}
cout<
当然,他没说必须排序,所以吗,根据冒泡排序的思想:
比较相邻两个数,小的往上浮,大的往下沉。
那我们直接迭代+比较不就完事了
用一个双重循环,完美解决,好像运行更快了!
#include
using namespace std;
int n, sum;
int main()
{
cin >> n;
int a[n];
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
for (int j = 0; j < i; ++j)
if (a[j] > a[i])
++sum;
cout << sum;
return 0;
}
思想:大模拟
先定义一个a数组,看每个位置会不会出怪兽,最后全扫一遍
为防止炸边界,我们先写一个判断函数:
bool check(int x,int y)
{
if(x>0 && x<=n && y>0 && y<=n)return 1;
}
void fire(int x,int y) //火把
{
for(int i=x-1;i<=x+1;i++)
for(int j=y-1;j<=y+1;j++)
if(check(i,j))a[i][j]=1;
//以下是防越界程序
if(check(x-2,y))a[x-2][y]=1; //左端
if(check(x+2,y))a[x+2][y]=1; //右端
if(check(x,y-2))a[x][y-2]=1; //下端
if(check(x,y+2))a[x][y+2]=1; //上端
}
void store(int x,int y) //萤石
{
//一个萤石的亮光区域是个3*3的矩阵
for(int i=x-2;i<=x+2;i++)
for(int j=y-2;j<=y+2;j++)
if(check(i,j))a[i][j]=1; //放炸+设置
}
下一步:该把主函数拼进去了
//以下的c是计数器,初始值为0
int main()
{
cin>>n>>m>>k; //读入
int x,y;
for(int i=1;i<=m;i++) //将火把的照明范围存档
{
cin>>x>>y;
fire(x,y);
}
for(int i=1;i<=k;i++) //将萤石的照明范围存档
{
cin>>x>>y;
store(x,y);
}
for(int i=1;i<=n;i++) //然后全扫一遍
{
for(int j=1;j<=n;j++)
{
//cout<
这就简单了。从头到尾找
数组都用不着。太高兴了!!!
代码走起来
#include
using namespace std;
int minn=10000010; //得来一个非常大的数,至少要大于1000
int n,i,x;
int main()
{
cin>>n;
for(i=1;i<=n;i++) //判断
{
cin>>x;
if(x
正常思路:扫一遍,一边扫一边统计,最后输出
所以直接上代码吧!
#include
using namespace std;
int t[10001]; // 存储器
int main()
{
int a,b,c=0;
cin>>a>>b; // 输入
for(int i=a;i<=b;i++) // 扫一遍
{
if(i%400==0 || i%4==0 && i%100!=0)
{
t[c]=i; //存进去
c++;
}
}
cout<
当然,也可以借助栈和队列帮助我们
以下展示一下栈的代码
注意:栈是先进后出,所以判断要反着判断
#include
using namespace std;
stack s;
int main()
{
int m,n,c=0;
cin>>m>>n;
for(int i=n;i>=m;i--) //反着判断
if(i%400==0 || i%4==0 && i%100!=0)
{
c++;
s.push(i); //入栈
}
cout<