只记录了自己A了的题,代码中的错误记录是为了提醒自己
裸题
#include<iostream>
using namespace std;
//dp[i] 以i结尾的最大值
const int N=1e5+10;
int dp[N];
int a[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>a[i];
}
dp[1]=a[1];
for(int i=2;i<=n;++i)
{
if(dp[i-1]>0)
dp[i]=dp[i-1]+a[i];
else
dp[i]=a[i];
}
int ans=0;
for(int i=1;i<=n;++i)
if(dp[i]>ans) ans=dp[i];
cout<<ans<<endl;
return 0;
}
节点由0-N-1表示,写静态二叉树能降低代码难度
核心在判断是否同构上
1、都为空树 true
2、一个空一个非空 false
3、根节点存储的数据不同 false
4、都没有左孩子 -> 判断右孩子是否同构
5、都有左孩子 (1)左孩子根结点存储数据相同 -> 判断左对左,右对右是否同构
(2)左孩子根结点存储数据不同 -> 判断左对右,右对左是否同构
6、一个有左孩子一个没有-> 判断判断左对右,右对左是否同构
#include<iostream>
#include<cstring>
using namespace std;
const int N=10;
struct node
{
char data;
int lchild;
int rchild;
}T1[N],T2[N];
int n,check[N];
int build(struct node T[])
{
int n,root;
cin>>n;
if(!n) return -1; //空树 根为-1
memset(check,0,sizeof(check));
for(int i=0;i<n;++i)
{
char l,r;
cin>>T[i].data>>l>>r;
if(l!='-')
{
T[i].lchild=l-'0';
check[T[i].lchild]=1;
}
else T[i].lchild=-1;
if(r!='-')
{
T[i].rchild=r-'0';
check[T[i].rchild]=1;
}
else T[i].rchild=-1;
}
int ind;
for(ind=0;ind<N;++ind)
if(!check[ind]) break;
return root=ind;
}
bool ok(int root1,int root2)
{
if(root1==root2&&root1==-1) return true; //都是空树
// if(root1!=root2) return false;
if(root1*root2<0) return false; //说明一个非空一个空
if(T1[root1].data!=T2[root2].data) return false;
if(T1[root1].lchild==-1&&T2[root2].lchild==-1) return ok(T1[root1].rchild,T2[root2].rchild);
if(T1[root1].lchild!=-1&&T2[root2].lchild!=-1&&T1[T1[root1].lchild].data==T2[T2[root2].lchild].data) //都有左孩子且左孩子根相同
return (ok(T1[root1].lchild,T2[root2].lchild)&&ok(T1[root1].rchild,T2[root2].rchild));
else //都有左孩子但是左孩子的根不同
return (ok(T1[root1].lchild,T2[root2].rchild)&&ok(T1[root1].rchild,T2[root2].lchild));
}
int main()
{
int root1,root2;
root1=build(T1);
root2=build(T2);
if(ok(root1,root2))
cout<<"Yes\n";
else cout<<"No\n";
return 0;
}
有了上一题的铺垫,这题就显得很容易
判断两颗数是否相同
1、都为空树 true
2、一个空一个非空 false
3、根节点存储的数据不同 false
4、两个孩子是否对应相同
#include<iostream>
using namespace std;
int n,l;
struct node
{
int data;
node *lchild;
node *rchild;
};
node* newnode(int v)
{
node* Node=new node;
Node->data=v;
Node->lchild=Node->rchild=NULL;
return Node;
}
void insert(node* &root,int x)
{
if(root==NULL) //如果是空树 则建立节点
{
root=newnode(x);
return ;
}
if(x==root->data) //二叉搜索树中不插入相同值
return;
else if(x<root->data)
insert(root->lchild,x);
else
insert(root->rchild,x);
}
node* create(int n)
{
node* root=NULL;
for(int i=0;i<n;++i)
{
int x;
cin>>x;
insert(root,x);
}
return root;
}
bool same(node* rt1,node* rt2)
{
if(rt1==NULL&&rt2==NULL) return true;
if((rt1!=NULL&&rt2==NULL)||(rt1==NULL&&rt2!=NULL)) return false;
if(rt1->data!=rt2->data) return false;
else return (same(rt1->lchild,rt2->lchild)&&same(rt1->rchild,rt2->rchild));
}
int main()
{
while(cin>>n)
{
if(!n) break;
cin>>l;
node* origin=create(n);
for(int i=1;i<=l;++i)
{
node* cp=create(n);
if(same(origin,cp))
cout<<"Yes\n";
else
cout<<"No\n";
}
}
return 0;
}
已经建好树再去算高度是这个样子的
int geth(node* root)
{
if(root==NULL) return 0;
int left=geth(root->lchild);
int right=geth(root->rchild);
return (left>right?left:right)+1;
}
a数组是preorder b数组是inorder, a数组中根在前面,根据根在b数组中的位置,将b数组分为左子树和右子树
[start,i)左子树,[i+1,end)是右子树。
#include<iostream>
#include<string>
using namespace std;
string a,b;
int num=-1;
int n;
int geth(int start,int end)
{
num++;
int i,j;
for(i=start;i<end;++i)
if(b[i]==a[num])
break;
if(i==end) return 0;
int left=0,right=0;
if(start<i) left=geth(start,i);
if(i+1<end) right=geth(i+1,end);
return left>right?left+1:right+1;
}
int main()
{
cin>>n;
cin>>a>>b;
cout<<geth(0,n)<<endl;
return 0;
}
看到有直接用make_heap()函数的
//#include<iostream>
//#include<algorithm>
//using namespace std;
//const int N=1e3+10;
//int heap[N];
//int n,m;
小顶堆
//void downjust(int low,int high)
//{
// int i=low,j=2*i;
// while(j<=high) //如果左儿子
// {
// if(j+1<=high&&heap[j+1]<heap[j])
// {
// swap(heap[j],heap[j+1]);
// }
// //j指向最小的儿子
// if(heap[i]>heap[j]) //j成为父亲
// {
// swap(heap[i],heap[j]);
// i=j;
// j=2*i;
// }
// else break; //父亲比儿子都小
// }
//
//}
//void createheap()
//{
// for(int i=n/2;i>=1;i--) //完全二叉树有ceil(n/2)个叶子节点。floor(n/2)个非叶节点
// downjust(i,n);
//}
//void output(int x)
//{
// cout<<heap[x];
// int i=x/2; //x的父节点为x/2
// while(i>=1)
// {
// cout<<' '<<heap[i];
// i/=2;
// }
//
// cout<<endl;
//}
//int main()
//{
// cin>>n>>m;
// for(int i=1;i<=n;++i)
// cin>>heap[i];
// createheap();
// for(int i=1;i<=m;++i)
// {
// int x;
// cin>>x;
// output(x);
// }
// return 0;
//
//}
左右孩子反了咋整 我交换了heap[j]和heap[j+1]
///*
//路径更长,交错,index从中间开始,有负数 Wrong Answer 3 ms 416 KB
//最大N和M随机,元素取到正负10000 Wrong Answer 7 ms 384 KB
//-10
//*/
//感到窒息,看了别人的博客
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int heap[N];
int n,m;
//小顶堆
void adjust(int x)
{
int fa;
while(x!=1)
{
fa=x/2;
if(heap[fa]>heap[x])
{
swap(heap[fa],heap[x]);
}
x=fa; //这种姿势是向上更新emm,把上面所有比自己大的都拽下来
}
}
void output(int x)
{
cout<<heap[x];
int i=x/2; //x的父节点为x/2
while(i>=1)
{
cout<<' '<<heap[i];
i/=2;
}
cout<<endl;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;++i)
{
cin>>heap[i];
adjust(i);
}
for(int i=1;i<=m;++i)
{
int x;
cin>>x;
output(x);
}
return 0;
}
#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
int g[15][15];
//vector<int> g[15];
//vector<int> ans;
int vis[15];
int n,e;
void dfs(int x)
{
vis[x]=1;
//ans.push_back(x);
cout<<x<<' ';
for(int i=0;i<n;++i)
{
if(!vis[i]&&g[x][i]==1)
dfs(i);
}
}
void bfs(int x)
{
queue<int> q;
q.push(x);
vis[x]=1;
cout<<x<<' ';
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<n;++i)
if(g[u][i]&&!vis[i])
{
q.push(i);
vis[i]=1;
cout<<i<<' ';
}
}
}
int main()
{
cin>>n>>e;
for(int i=1;i<=e;++i)
{
int u,v;
cin>>u>>v;
g[u][v]=1;
g[v][u]=1;
}
memset(vis,0,sizeof(vis));
for(int i=0;i<n;++i)
{
if(!vis[i])
{
cout<<"{ ";
dfs(i);
cout<<"}\n";
//ans.clear();
}
}
memset(vis,0,sizeof(vis));
for(int i=0;i<n;++i)
{
if(!vis[i])
{
cout<<"{ ";
bfs(i);
cout<<"}\n";
//ans.clear();
}
}
return 0;
}
一开始错误是没有考虑到图不连通,直接想以cnt==n判断最后一个是否不需要再输出一次
在用栈结构的时候就应该同时想到 递归实现的。。。
#include<iostream>
#include<vector>
#include<algorithm>
#include<stack>
using namespace std;
int n,m,s;
const int N=1e3+10;
int vis[N];
stack<int> st;
vector<int> g[N];
int cnt=0;
void dfs(int x)
{
int flag=0;
vis[x]=1;
++cnt;
if(x==s)
cout<<x;
else
{
cout<<' '<<x;
}
// if(cnt!=n)
// st.push(x);
sort(g[x].begin(),g[x].end());
for(int i=0;i<g[x].size();++i)
{
int v=g[x][i];
if(!vis[v])
{
//flag=1;
//st.push(x);
dfs(v);
cout<<' '<<x; //巧妙
}
// else if(!vis[v])
// dfs(v);
}
}
int main()
{
cin>>n>>m>>s;
for(int i=1;i<=m;++i)
{
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(s);
if(cnt<n)
cout<<' '<<0<<endl;
return 0;
}
/*
路径中某结点被访问多次 Wrong Answer 2 ms 368 KB
3 最大N和M Wrong Answer 6 ms 544 KB
-10
*/
//dfs走出来的不是最短的
#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=1e4+10;
const int INF=0x3f3f3f3f;
vector<int> g[N];
int deep[N];
int vis[N];
int n,m;
int bfs(int u)
{
memset(vis,0,sizeof(vis));
memset(deep,INF,sizeof(deep));
queue<int> q;
q.push(u);
vis[u]=1;
deep[u]=0;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=0;i<g[x].size();++i)
{
int v=g[x][i];
if(!vis[v])
{
vis[v]=1;
deep[v]=deep[x]+1;
q.push(v);
}
}
}
int cnt=0;
for(int i=1;i<=n;++i)
{
if(deep[i]<=6)
++cnt;
}
return cnt;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;++i)
{
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
// bfs(1);
for(int i=1;i<=n;++i)
{
//cout<<bfs(i)<<endl;
double ans=100.0*bfs(i)/n;
printf("%d: %.2lf%%\n",i,ans);
}
return 0;
}
7-36 社交网络图中结点的“重要性”计算 (30 point(s))
注意判断非连通,以及cout<<0.00;输出的会是0
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<vector>
#include<iomanip>
using namespace std;
const int N=1e4+10;
vector<int> g[N];
int depth[N];
int n,m;
int bfs(int x)
{
queue<int>q;
int num=0;
memset(depth,-1,sizeof(depth));
q.push(x);
depth[x]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
++num;
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i];
if(depth[v]==-1)
{
depth[v]=depth[u]+1;
q.push(v);
}
}
}
int ans=0;
if(num<n) return 0;
for(int i=1;i<=n;++i)
{
ans+=depth[i];
}
return ans;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;++i)
{
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
int k;
cin>>k;
while(k--)
{
int x;
cin>>x;
int tmp=bfs(x);
double ans;
if(!tmp) ans=0;
else ans=1.0*(n-1)/tmp;
cout<<"Cc("<<x<<")="<<fixed<<setprecision(2)<<ans<<endl;
}
}
A->B需要的咒语长度相当于A->B 的最短路,咒语长度就是路径长度
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
const int N=110;
const int INF=0x3f3f3f3f;
int dist[N][N];
int main()
{
cin>>n>>m;
memset(dist,INF,sizeof(dist));
for(int i=1;i<=n;++i)
dist[i][i]=0;
for(int i=1;i<=m;++i)
{
int u,v,w;
cin>>u>>v>>w;
dist[u][v]=w;
dist[v][u]=w;
}
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
int idx=1;
int ans=INF;
for(int i=1;i<=n;++i)
{
int mx=0;
for(int j=1;j<=n;++j)
mx=max(mx,dist[i][j]);
if(ans>mx)
{
ans=mx;
idx=i;
}
}
if(ans==INF) cout<<0<<endl;
else cout<<idx<<' '<<ans<<endl;
return 0;
}
7-9 旅游规划 (25 point(s))--路径相同的时候价格最小
一开始一直最后一个点过不了,是存边的数组开小了,我记得把它开成完全图的大小也不行来着。。。
在路径相同的时候记得更新一下价格即可
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
int head[1010];
int dist[1010];
int c[1010];
int cnt=0;
struct edge
{
int v,w,next,cost;
edge(){}
edge(int v,int w,int next,int cost):v(v),w(w),next(next),cost(cost){}
}e[250000];
void addedge(int u,int v,int w,int cost)
{
e[cnt]=edge(v,w,head[u],cost);
head[u]=cnt++;
}
void dijkstra(int s)
{
memset(dist,INF,sizeof(dist));
memset(c,0,sizeof(c));
priority_queue<pii,vector<pii>,greater<pii> > q;
dist[s]=0;
q.push(pii(dist[s],s));
while(!q.empty())
{
pii p=q.top();
q.pop();
int u=p.second, d=p.first;
if(d>dist[u]) continue;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(d+e[i].w<dist[v])
{
dist[v]=d+e[i].w;
c[v]=c[u]+e[i].cost;
q.push(pii(dist[v],v));
}
else if(d+e[i].w==dist[v])
{
dist[v]=d+e[i].w;
c[v]=min(c[v],c[u]+e[i].cost);
//q.push(pii(dist[v],v));
}
}
}
}
int main()
{
memset(head,-1,sizeof(head));
int n,m,s,d;
cin>>n>>m>>s>>d;
for(int i=1;i<=m;++i)
{
int u,v,w,cost;
cin>>u>>v>>w>>cost;
addedge(u,v,w,cost);
addedge(v,u,w,cost);
}
dijkstra(s);
cout<<dist[d]<<' '<<c[d]<<endl;
}
7-35 城市间紧急救援 (25 point(s))->最短路径的条数和能够召集的最多的救援队数量
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
int head[1010];
int dist[1010];
int dp[1010]; //dp[i]记录到达i的最短路有多少条
int pre[1010];
int a[1010];
int c[1010]; //c代表召集的人
int cnt=0;
//queue<int>ans;
struct edge
{
int v,w,next,cost;
edge(){}
edge(int v,int w,int next):v(v),w(w),next(next){}
}e[250000];
void addedge(int u,int v,int w)
{
e[cnt]=edge(v,w,head[u]);
head[u]=cnt++;
}
void dijkstra(int s)
{
memset(dist,INF,sizeof(dist));
//memset(c,0,sizeof(c));
priority_queue<pii,vector<pii>,greater<pii> > q;
dist[s]=0;
dp[s]=1;
q.push(pii(dist[s],s));
while(!q.empty())
{
pii p=q.top();
q.pop();
int u=p.second, d=p.first;
if(d>dist[u]) continue;
//ans.push(u);
// cout<<c[s]<<endl;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(d+e[i].w<dist[v])
{
dist[v]=d+e[i].w;
c[v]=c[u]+a[v];
// cout<<u<<"->"<<v<<'='<<c[v]<<endl;
q.push(pii(dist[v],v));
dp[v]=dp[u];
pre[v]=u;
}
else if(d+e[i].w==dist[v])
{
dp[v]+=dp[u];
if(c[u]+a[v]>c[v])
{
c[v]=c[u]+a[v];
pre[v]=u;
}
//q.push(pii(dist[v],v));
}
}
}
}
int main()
{
memset(head,-1,sizeof(head));
memset(pre,-1,sizeof(pre));
int n,m,s,d;
cin>>n>>m>>s>>d;
for(int i=0;i<n;++i)
{
cin>>a[i];
c[i]=a[i];
}
for(int i=1;i<=m;++i)
{
int u,v,w,cost;
cin>>u>>v>>w;
addedge(u,v,w);
addedge(v,u,w);
}
dijkstra(s);
cout<<dp[d]<<' '<<c[d]<<endl;
// for(int i=1;i<=n;++i)
// cout<<pre[i]<<endl;
int cnt=0;
int pp=d;
vector<int>v;
while(pp!=-1)
{
v.push_back(pp);
pp=pre[pp];
cnt++;
}
cout<<v[cnt-1];
for(int i=cnt-2;i>=0;--i)
cout<<' '<<v[i];
cout<<endl;
// cout<<pre[d]<<endl;
// int i=d-1;
// while(pre[i]!=-1)
// {
// cout<<' '<<pre[i];
// i=pre[i];
// }
return 0;
}
/*
3 最大N和M,随机数据构成完全图 Segmentation Fault 11 ms 512 KB
*/
7-50 畅通工程之局部最小花费问题 (35 point(s))
算是简单的一道最小生成树
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110;
int fa[N];
int n;
int cnt=0;
struct edge
{
int u,v,w;
edge(){}
edge(int u,int v,int w):u(u),v(v),w(w){}
bool operator < (const edge &rhs)const
{
return w<rhs.w;
}
}e[5010];
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
int main()
{
cin>>n;
for(int i=1;i<=n;++i)
fa[i]=i;
int num=0;
for(int i=1;i<=n*(n-1)/2;++i)
{
int u,v,w,flag;
cin>>u>>v>>w>>flag;
if(flag)
{
int fx=find(u);
int fy=find(v);
if(fx!=fy)
{
fa[fx]=fy;
num++; //记录边数
}
}
else
e[cnt++]=edge(u,v,w);
}
sort(e,e+cnt);
int ans=0;
if(num==n-1) {cout<<ans<<endl;return 0;}
for(int i=0;i<cnt;++i)
{
int u=e[i].u,v=e[i].v,w=e[i].w;
int fx=find(u);
int fy=find(v);
if(fx!=fy)
{
fa[fx]=fy;
num++; //记录边数
ans+=w;
}
if(num==n-1)
break;
}
cout<<ans<<endl;
return 0;
}
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<vector>
#include<iomanip>
#include<set>
#include<cstdio>
using namespace std;
const int N=1e4+10;
//multiset<int>s;
vector<int>v;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)
{
int a;
scanf("%d",&a);
//s.insert(a);
v.push_back(a);
}
sort(v.begin(),v.end(),greater<int>());
for(int i=0;i<m;++i)
{
if(i<n)
{
if(!i)
printf("%d",v[i]);
else printf(" %d",v[i]);
}
}
// int k=0;
// set<int>::reverse_iterator rit;
// for(rit=s.rbegin();rit!=s.rend();++rit)
// {
// if(!k) cout<<*rit;
// else cout<<' '<<*rit;
// ++k;
// if(k==m) break;
// }
printf("\n");
return 0;
}
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
map<int,int> mp;
const int N=1e5+10;
int a[N];
int main()
{
int n;
cin>>n;
int mx=-1;
for(int i=1;i<=n;++i)
{
cin>>a[i];
mx=max(mx,a[i]);
}
for(int i=1;i<=n;++i)
mp[a[i]]++;
for(int i=0;i<=mx;++i)
if(mp[i])
cout<<i<<':'<<mp[i]<<endl;
// sort(a+1,a+1+n);
return 0;
}
一开始因为存int -8分
#include<iostream>
#include<map>
using namespace std;
typedef long long LL;
map<LL,string> mp;
int n;
int main()
{
cin>>n;
while(n--)
{
char ch;
LL num;
string mi;
cin>>ch>>num>>mi;
if(ch=='N')
{
if(mp.find(num)!=mp.end())
cout<<"ERROR: Exist\n";
else
{
mp[num]=mi;
cout<<"New: OK\n";
}
}
else if(ch=='L')
{
if(mp.find(num)==mp.end())
cout<<"ERROR: Not Exist\n";
else if(mi!=mp[num])
cout<<"ERROR: Wrong PW\n";
else
cout<<"Login: OK\n";
}
// cout<<order<<num<<mi<<endl;
}
return 0;
}
/* -8
N和L指令各一半,随机交错。帐号随机,取到上下界。密码随机,取到上下界 Wrong Answer
*/
这道题用cin会T
//用栈实现
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
struct node
{
char a,b,c;
int n;
node(){}
node(int n,char a,char b,char c): n(n),a(a),b(b),c(c){}
};
int main()
{
//ios::sync_with_stdio(false);
int n;
scanf("%d",&n);
stack<node>s;
//s.push(node(n,'a','b','c'));
node x;
x.n=n,x.a='a',x.b='b',x.c='c';
s.push(x);
while(!s.empty())
{
node p=s.top();
s.pop();
if(p.n==1)
printf("%c -> %c\n",p.a,p.c);
//cout<<p.a<<" -> "<<p.c<<endl;
else
{
x.n=p.n-1,x.a=p.b,x.b=p.a,x.c=p.c;
s.push(x);
x.n=1,x.a=p.a,x.b=p.b,x.c=p.c;
s.push(x);
x.n=p.n-1,x.a=p.a,x.b=p.c,x.c=p.b;
s.push(x);
}
}
return 0;
}
//仍然未A
/*
3 较大N Time Limit Exceeded 0 ms 0 KB -6
*/
/*
b->c
a->c
a->b
*/
/*
a->b
a->c
b->c
#include<stdio.h>
void han(int n,char a,char b,char c)
{
if(n==1) printf("%c -> %c\n",a,c);
else
{
han(n-1,a,c,b);
printf("%c -> %c\n",a,c);
han(n-1,b,a,c);
}
}
int main()
{
int n;
scanf("%d",&n);
han(n,'a','b','c');
return 0;
---------------------
参考原文:https://blog.csdn.net/s136424/article/details/78132623
*/