两个题没写,被恶心到了,也许也是我太菜了,如果有疑问或者纠错,或者想告诉我某些我不会的题的思路。可以评论区发给我,我很乐意的,。。。另外我程设居然过了,感谢谢大手下留情......

1.逆序数(大数据)-1167

样例输入

3
3 1 2
4
1 2 3 4
0

样例输出

2
0

思路:只能归并排序和树状数组,这里我讲讲归并排序。

很好理解,只是自己还是不会敲出来,就是从中间开始分,同时排序左右两边,在左边基础上又分为左右两边,在右边的基础上又分为左右两边,将大的排序分为小的排序,排序完成然后全部整合。

在排序的过程中你会发现,左边还没来得及复制的T就是所以比a[j]大的数,所以加m-q即可。

Memory: 1516K Time: 234MS
#include <stdio.h>
#include <string.h>
using namespace std;
int a[10001];
int temp[10001];//中介,这个是排序后的结果
int res=0;
void MergeSort(int x,int y)
{if(y-x>1){int sum=0;int m=(x+y)/2;int p=x,q=m,i=x;MergeSort(x,m);MergeSort(m,y);while(p<m||q<y){if(q>=y||(p<m&&a[p]<=a[q])){temp[i++]=a[p++];}else{temp[i++]=a[q++];sum+=m-p;//x_______m_______y,p在x-m之间,q在m-y之间}}for(int i=x;i<y;i++){a[i]=temp[i];}res+=sum;}
}
int main()
{int n;scanf("%d",&n);while(n!=0){res=0;memset(a,0,sizeof(a));memset(temp,0,sizeof(temp));for(int i=0;i<n;i++){scanf("%d",&a[i]);}MergeSort(0,n);/*for(int i=0;i<n;i++){printf("%d ",a[i]);}*/printf("%d\n",res);scanf("%d",&n);}return 0;
}

2.1179-Shortest Path

样例输入

3 3 1
1 2 3
2 3 4
1 3 2
2
0 0 0

样例输出

7

思路:dijkstra算法。但是注意啊,有重边取最小,而且必须按顺序经过且只能经过一次,所以一开始就得有路径被标记成已经走过,举个栗子。

1----a1----a2----a3----n

从1开始必须终点是a1,所以,a2,a3,n它不能走。

a1的终点是a2,因此1,a3,n它不能走。

a2,1,a1,n不能走。

......

所以开始就标记已经走过即可。

Memory: 6120K Time: 1999MS
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <string.h>
#include <limits.h>
typedef long long ll;
using namespace std;
int d[1101];
int vis[1101];
int s[1101][1101];
int n,m,k;
struct node
{int x,y;bool operator<(const node&b)const{return y>b.y;}
};
void djsrt(int t)
{fill(d,d+1101,INT_MAX/2);d[t]=0;priority_queue<node>q;node temp;temp.x=t,temp.y=0;q.push(temp);while(!q.empty()){node st=q.top();q.pop();if(vis[st.x]==1){continue;}vis[st.x]=1;int a=st.x;for(int i=0;i<n;i++){if(vis[i]==0&&s[a][i]<INT_MAX/2){if(d[i]>d[a]+s[a][i]){d[i]=d[a]+s[a][i];q.push((node){i,d[i]});}}}}
}
int main()
{//FILE *fpRead=fopen("D://huancun//1179//std.in","r");scanf("%d%d%d",&n,&m,&k);while(1){if(n==m&&m==k&&k==0){break;}int a[3];memset(a,0,sizeof(a));fill(s[0],s[0]+1101*1101,INT_MAX/2);for(int i=0;i<m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);if(s[a-1][b-1]>c){s[a-1][b-1]=c;s[b-1][a-1]=c;}}for(int i=0;i<k;i++){scanf("%d",&a[i]);}ll res=0;memset(vis,0,sizeof(vis));if(k==0){//暴力一点,看得更清楚djsrt(0);res+=d[n-1];}else if(k==1){vis[n-1]=1;//标记djsrt(0);res+=d[a[0]-1];memset(vis,0,sizeof(vis));vis[0]=1;djsrt(a[0]-1);res+=d[n-1];}else if(k==2){vis[n-1]=1;//标记vis[a[1]-1]=1;djsrt(0);res+=d[a[0]-1];memset(vis,0,sizeof(vis));vis[n-1]=1;vis[0]=1;djsrt(a[0]-1);res+=d[a[1]-1];memset(vis,0,sizeof(vis));vis[0]=1;vis[a[0]-1]=1;djsrt(a[1]-1);res+=d[n-1];}else if(k==3){vis[n-1]=1;//标记vis[a[1]-1]=1;vis[a[2]-1]=1;djsrt(0);res+=d[a[0]-1];memset(vis,0,sizeof(vis));vis[n-1]=1;vis[0]=1;vis[a[2]-1]=1;djsrt(a[0]-1);res+=d[a[1]-1];memset(vis,0,sizeof(vis));vis[n-1]=1;vis[0]=1;vis[a[0]-1]=1;djsrt(a[1]-1);res+=d[a[2]-1];memset(vis,0,sizeof(vis));vis[0]=1;vis[a[0]-1]=1;vis[a[1]-1]=1;djsrt(a[2]-1);res+=d[n-1];}if(res>=INT_MAX/2){printf("Impossible\n");}else{printf("%lld\n",res);}scanf("%d%d%d",&n,&m,&k);}return 0;
}

3.1195-Large Population

Sample Input

2
2 1
1 2 1
3 3
1 2 1
1 3 2
2 3 3

Sample Output

1
5

思路:prim()算法,要求最大,我们只需要反过来把输入变成负数,因为prim求的是最小,这样求出来之后然后取反即可。注意重边,当时long好像不能用,所以只能用I64。

Memory: 9224K Time: 1343MS
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <limits.h>
using namespace std;
typedef long long ll;
__int64 matx[1011][1011];
__int64 visited[1011];
__int64 d[1011];
int n,m;
__int64 prim()
{fill(d,d+1010,INT_MAX);d[0]=0;__int64 res=0;for(int i=0;i<n;i++){__int64 mins=INT_MAX,id=0;for(int j=0;j<n;j++){if(visited[j]==0&&d[j]<mins){id=j;mins=d[j];}}//printf("%d ",id);visited[id]=1;res+=d[id];//printf("%lld\n",res);for(int k=0;k<n;k++){if(visited[k]==0&&matx[id][k]!=INT_MAX&&matx[id][k]<d[k]){d[k]=matx[id][k];}}}return res;
}
int main()
{int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);memset(visited,0,sizeof(visited));fill(matx[0],matx[0]+1010*1010,INT_MAX);for(int i=0;i<m;i++){int a,b;__int64 c;scanf("%d%d%I64d",&a,&b,&c);if(matx[a-1][b-1]>-c){matx[a-1][b-1]=-c;matx[b-1][a-1]=-c;}}__int64 res=prim();printf("%I64d\n",-res);}return 0;
}

4.1245-Lisa's Puzzle

样例输入

5
5
13
1
2
3

样例输出

1
0
3
0
0

思路:这个题目很有意思,我们可以把它当做一个字典树,因为是二进制,所以是二叉字典树,树的每一个节点都可以表示一个数,这样后缀就可以直观看到了。

Memory: 26352K Time: 968MS
#include <stdio.h>
#include <unordered_map>
using namespace std;
typedef long long ll;
ll b[100010]={0};
int main()
{unordered_map<ll,ll>a;int n;scanf("%d",&n);int t=0;while(n--){ll m;scanf("%lld",&m);b[t++]=m;ll ans=0;while(m!=0){if(m%2==1){ans=ans*2+2;a[ans]++;}else{ans=ans*2+1;a[ans]++;}m/=2;}}for(ll i=0;i<t;i++){ll ans=0;ll res=INT_MAX;while(b[i]!=0){if(b[i]%2==1){ans=ans*2+2;res=min(res,a[ans]);}else{ans=ans*2+1;res=min(res,a[ans]);}b[i]/=2;}printf("%lld\n",res-1);}return 0;
}

5.1250-Bonus

样例输入

2
3 2
1 2
2 3
3 2
1 2
2 1

样例输出

5664
2888 1888 888
2664
888 888 888

思路:拓扑和bfs选一个即可,只是题意感觉不怎么明白。参考了别人的题解。

Memory: 4200K Time: 452MS
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
typedef long long ll;
vector<ll>res[10010];
ll s[10010],vis[10010];
ll dfs(ll nums)
{vis[nums]=-1;//正在访问for(ll i=0;i<res[nums].size();++i){ll id=res[nums][i];if(vis[id]<0){return -1;}if(vis[id]==0){s[id]=dfs(id);}if(s[id]<0){return -1;}if(s[nums]<s[id]+1000){s[nums]=s[id]+1000;}}vis[nums]=1;return s[nums];
}
ll ts(ll n)
{memset(vis,0,sizeof(vis));for(ll i=1;i<=n;i++){if(!vis[i]&&dfs(i)<0){return -1;}}return 0;
}
int main()
{ll t;scanf("%lld",&t);while(t--){ll n,m;scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++){res[i].clear();s[i]=888;}for(ll i=0;i<m;i++){ll a,b;scanf("%lld%lld",&a,&b);res[a].push_back(b);}ll sum=0;if(ts(n)<0){sum=n*888;printf("%lld\n",sum);for(ll i=1;i<n;i++){printf("%lld ",888);}printf("888\n");}else{for(ll i=1;i<=n;i++){sum+=s[i];}printf("%lld\n",sum);for(ll i=1;i<n;i++){printf("%lld ",s[i]);}printf("%lld\n",s[n]);}}return 0;
}

6.1288-Binary Search Tree

样例输入

2
5 5
3 2 5 1 4
3 1 2 5 4
3 2 1 5 4
3 5 2 1 4
3 5 4 2 1
3 2 4 5 1
3 2
1 2 3
1 3 2
3 2 1

样例输出

1: No
2: Yes
3: Yes
4: Yes
5: No1: No
2: No

思路:中+前/后序遍历绝对一棵树 ,所以最直观的方法就是前序或者后续遍历即可,还能优化一下,但是能过已经够了。

Memory: 63808K Time: 1734MS
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
int ch[1001],flag=0,ans=0;
struct Treenode
{int val;Treenode *l;Treenode *r;
};
Treenode* create(Treenode* t)//二叉树模板
{t=new Treenode;t->l=nullptr;t->r=nullptr;return t;
}
Treenode* into(Treenode* t,int val)
{if(t==nullptr){t=create(t);t->val=val;return t;}if(val<t->val){t->l=into(t->l,val);return t;}if(val>t->val){t->r=into(t->r,val);return t;}
}
void pre(Treenode* t)//前序
{if(t==nullptr){return;}ch[ans++]=t->val;pre(t->l);pre(t->r);
}
void pres(Treenode* t)//前序
{if(t==nullptr){return;}if(ch[ans++]!=t->val){flag=1;return;}pres(t->l);pres(t->r);
}
int main()
{int t;scanf("%d",&t);while(t--){int n,m;flag=0,ans=0;scanf("%d%d",&n,&m);memset(ch,0,sizeof(ch));Treenode *root=nullptr;for(int i=0;i<n;i++){int nums;scanf("%d",&nums);root=into(root,nums);}pre(root);for(int i=0;i<m;i++){flag=0;ans=0;Treenode *t=nullptr;for(int j=0;j<n;j++){int nums;scanf("%d",&nums);t=into(t,nums);}pres(t);if(flag==0){printf("%d: Yes\n",i+1);}else{printf("%d: No\n",i+1);}}printf("\n");free(root);}return 0;
}

7.1302-Balance Tree

样例输入

3
5
4 3 2 1 5
5
3 4 2 1 5
5
4 2 1 3 5

样例输出

No
Yes
Yes

思路:跟上题目是同一个类型的,我们只需要学会找二叉树深度,这个题目就挺简单了。

Memory: 4708K Time: 125MS
#include <stdio.h>
#include <algorithm>
using namespace std;
struct Treenode
{int val;Treenode *l;Treenode *r;
};
int flag=0;
Treenode* create(Treenode* t)//二叉树模板
{t=new Treenode;t->l=nullptr;t->r=nullptr;return t;
}
Treenode* into(Treenode* t,int val)
{if(t==nullptr){t=create(t);t->val=val;return t;}if(val<t->val){t->l=into(t->l,val);return t;}if(val>t->val){t->r=into(t->r,val);return t;}
}
int dfs(Treenode *t)//求深度
{if(t==nullptr){return 0;}int left=dfs(t->l);int right=dfs(t->r);if(abs(left-right)>1){//左子树和右子树深度flag=1;return max(left,right)+1;}return max(left,right)+1;
}
int main()
{int t;scanf("%d",&t);while(t--){flag=0;int n;scanf("%d",&n);Treenode *root=nullptr;for(int i=0;i<n;i++){int nums;scanf("%d",&nums);root=into(root,nums);}dfs(root);if(flag==0){printf("Yes\n");}else{printf("No\n");}}return 0;
}

8.1369-Black White Chess

样例输入

5
0000000000000000
1111111111111111
0000111100001111
1000000000000000
1100000000000011

样例输出

0
0
2
-1
4

思路:一遍bfs即可,找到所有的可能,计算最小。

Memory: 7652K Time: 514MS
#include <iostream>
#include <queue>
#include <unordered_map>
typedef long long ll;
using namespace std;
unordered_map<string,ll>hashmap;
int a[10001];
string cows(string s,int n)//行
{for(int i=n*4;i<n*4+4;i++){if(s[i]=='0'){s[i]='1';}else{s[i]='0';}}return s;
}
string rows(string s,int n)//列
{for(int i=n;i<n+16;i+=4){if(s[i]=='0'){s[i]='1';}else{s[i]='0';}}return s;
}
string mids(string s,int n)//四个
{for(int i=n;i<n+2;i++){if(s[i]=='0'){s[i]='1';}else{s[i]='0';}}for(int i=n+4;i<n+6;i++){if(s[i]=='0'){s[i]='1';}else{s[i]='0';}}return s;
}
void bfs()//bfs
{string s;pair<string,ll>res;queue<pair<string,ll>>p;int ans=1;for(int i=0;i<16;i++){//初始化两个原状态s+='0';}res.first=s;res.second=0;p.push(res);for(int i=0;i<16;i++){s[i]='1';}res.first=s;res.second=0;p.push(res);while(!p.empty()){string sp=p.front().first;int x=p.front().second;p.pop();if(hashmap[sp]!=0){//maps储存是否已经出现continue;}else{hashmap[sp]=ans++;}a[hashmap[sp]]=x;//x是最小次数//cout<<sp<<" "<<x<<endl;for(int i=0;i<4;i++){p.push({cows(sp,i),x+1});}for(int i=0;i<4;i++){p.push({rows(sp,i),x+1});}for(int i=0;i<3;i++){p.push({mids(sp,i),x+1});}for(int i=4;i<7;i++){p.push({mids(sp,i),x+1});}for(int i=8;i<11;i++){p.push({mids(sp,i),x+1});}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);int t;cin>>t;bfs();while(t--){string m;cin>>m;if(hashmap[m]==0){cout<<-1<<endl;}else{cout<<a[hashmap[m]]<<endl;}}return 0;
}

9.1370-Ball

样例输入

4
3 2
1 2
2 33 2
1 2
1 37 6
1 3
2 3
3 4
4 5
5 6
5 75 6
1 2
1 3
1 4
1 5
2 3
2 4

样例输出

2
0
4
0

思路:当时我是真的没有想到用Floyd算法,我们先把每个边根据Floyd初始化,然后使用一次Floyd,然后看每个点与其他的点的距离是否是无限大,如果是无限大那么说明出度或者入度就0,否则入度或者出度+1,最后再比较入度和出度是否都是一半。

Memory: 1248K Time: 77MS
#include <stdio.h>
#include <string.h>
#include <limits.h>
using namespace std;
int d[101][101];
int main()
{int t;scanf("%d",&t);while(t--){int n,m;scanf("%d%d",&n,&m);memset(d,0,sizeof(d));for(int i=0;i<n;i++){for(int j=0;j<n;j++){//Floyd初始化if(i==j){d[i][j]=0;}else{d[i][j]=INT_MAX/2;}}}for(int i=0;i<m;i++){int a,b;scanf("%d%d",&a,&b);d[a-1][b-1]=1;}for(int i=0;i<n;i++){//Floydfor(int j=0;j<n;j++){for(int k=0;k<n;k++){if(d[j][k]>d[j][i]+d[i][k]){d[j][k]=d[j][i]+d[i][k];}}}}//cout<<d[0][1]<<endl;//cout<<INT_MAX/2;int flag=0;for(int i=0;i<n;i++){int a=0;for(int j=0;j<n;j++){if(d[i][j]!=0&&d[i][j]!=INT_MAX/2){//如果不是无限大,说明有出度或者入度if(d[i][j]>0){/*if(i==1)cout<<i<<" "<<j<<" "<<d[i][j]<<endl;*/a++;}}}if(a==(n-1)/2){//如果入度或者出度中的一个等于中间,那么继续寻找出度或者入度a=0;for(int k=0;k<n;k++){if(d[k][i]!=0&&d[k][i]!=INT_MAX/2){a++;}}if(a==(n-1)/2){//两个都是的话说明是中间的了flag=1;printf("%d\n",i+1);}}}if(flag==0){printf("%d\n",0);}}return 0;
}

10.1378-Blocks

以前的博客有,可以去翻我以前的题解。

11.1387-打字机

不想写wwww

12.1389-二叉查找树

样例输入

2
5
3 2 1 4 5
5
4 5 3 2 1

样例输出

1
2

思路:模板题,没什么说的。

Memory: 14952K Time: 546MS
#include <stdio.h>
#include <algorithm>
using namespace std;
struct Treenode
{int val;Treenode *l;Treenode *r;
};
int mins=0;
Treenode* create(Treenode* t)
{t=new Treenode;t->l=nullptr;t->r=nullptr;return t;
}
Treenode* into(Treenode* t,int val)
{if(t==nullptr){t=create(t);t->val=val;return t;}if(val<t->val){t->l=into(t->l,val);return t;}if(val>t->val){t->r=into(t->r,val);return t;}
}
int dfs(Treenode *t)
{if(t==nullptr){return 0;}int left=dfs(t->l);int right=dfs(t->r);mins=max(abs(left-right),mins);return max(left,right)+1;
}
int main()
{int t;scanf("%d",&t);while(t--){mins=0;int n;scanf("%d",&n);Treenode *root=nullptr;for(int i=0;i<n;i++){int nums;scanf("%d",&nums);root=into(root,nums);}dfs(root);printf("%d\n",mins);}return 0;
}

13.1398-积木II

样例输入

2
6 3
9 3

样例输出

2
6

思路:其实跟积木I没什么区别,我们想一想,积木经过全排列后,我们只需要从中拿出一段排好序列放到后面,就是这个题目的意思了,那么拿出的方式有

是不是很神奇?那你就大错特错了,其实题解上这个公式思路是对的,但是运算并不是这个,其实实际的m应该是m-1,因为你排好序后最后最大的那一位是不能动的。

Memory: 1732K Time: 312MS
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
int main()
{int t;scanf("%d",&t);while(t--){int n,m;int dp[110][11][110];memset(dp,0,sizeof(dp));dp[1][1][1]=1;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){for(int k=1;k<=i;k++){if(j==1){if(i==k)dp[i][j][k]=1;else dp[i][j][k]=0;}else{for(int s=k-1;s>=1;s--){dp[i][j][k]+=dp[i-k][j-1][s];}}}}}int res=0;for(int i=1;i<=n;i++){res+=dp[n][m][i];}res*=pow(2,m-1)-2;//最终结果应该是m-1printf("%d\n",res);}return 0;
}

14.1409-Splite

样例输入

2
5 2
1 2 3 4 5
5 3
1 5 2 4 3

样例输出

17
15

思路:典型的dp题,一定要注意初始化啊!!!!

Memory: 1480K Time: 0MS
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;int main()
{int t;scanf("%d",&t);while(t--){int a[51];int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);}int dp[55][55];memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++){dp[i][1]=abs(a[i]-a[1])*i;}dp[1][1]=a[1];for(int i=1;i<=n;i++){for(int k=1;k<=m;k++){if(k==1){continue;}for(int j=i-1;j>=0;j--){if(k-1>j){dp[i][k]=max(dp[i][k],dp[i-1][k-1]+a[i]);continue;}dp[i][k]=max(dp[i][k],max(dp[i-1][k-1]+a[i],dp[j][k-1]+(i-j)*abs(a[j+1]-a[i])));}}}printf("%d\n",dp[n][m]);}return 0;
}

15.1410-Anniversary

样例输入

1
4 7 2
1 2 7
1 3 2
2 3 1
3 2 2
3 4 5
2 1 3
4 2 3

样例输出

9

思路:构造一个正图,一个反图,分别使用dijkstra算法。

Memory: 9228K Time: 1375MS
#include <stdio.h>
#include <queue>
#include <string.h>
#include <algorithm>
#include <limits.h>
using namespace std;
int s[1001][1001];
int s2[1001][1001];
int d[1001];
int vis[1001], n, m, e;
int p[1001],g[1001];
struct node
{int a, b;bool operator<(const node&c)const{return b > c.b;}
};
void djstr(int st)
{fill(d, d + 1001, INT_MAX/2);d[st] = 0;priority_queue<node>q;node t;t.a = st, t.b = 0;q.push(t);memset(vis, 0, sizeof(vis));while (!q.empty()) {node x = q.top();q.pop();int a = x.a;if (vis[a] == 1) {continue;}vis[a] = 1;for (int i = 0;i < n;i++) {if (!vis[i] && s[a][i] < INT_MAX/2) {if (d[i] > d[a] + s[a][i]) {d[i] = d[a] + s[a][i];node temp;temp.a = i;temp.b = d[i];q.push(temp);}}}}
}
void djstr1(int st)
{fill(d, d + 1001, INT_MAX / 2);d[st] = 0;priority_queue<node>q;node t;t.a = st, t.b = 0;q.push(t);memset(vis, 0, sizeof(vis));while (!q.empty()) {node x = q.top();q.pop();int a = x.a;if (vis[a] == 1) {continue;}vis[a] = 1;for (int i = 0;i < n;i++) {if (!vis[i] && s2[a][i] < INT_MAX / 2) {if (d[i] > d[a] + s2[a][i]) {d[i] = d[a] + s2[a][i];//printf("%d ", d[i]);node temp;temp.a = i;temp.b = d[i];q.push(temp);}}}}
}
int main()
{int t;scanf("%d", &t);while (t--) {memset(p, 0, sizeof(p));memset(g, 0, sizeof(g));fill(s[0], s[0] + 1001 * 1001, INT_MAX/2);fill(s2[0], s2[0] + 1001 * 1001, INT_MAX / 2);scanf("%d%d%d", &n, &m, &e);for (int i = 0;i < m;i++) {int x, y, z;scanf("%d%d%d", &x, &y, &z);if (s[x - 1][y - 1] > z) {s[x - 1][y - 1] = z;s2[y - 1][x - 1] = z;}}djstr(e - 1);for(int i = 0;i < n;i++) {g[i] = d[i];//e到各个节点}djstr1(e - 1);for (int i = 0;i < n;i++) {p[i] = d[i];}int res = -1;for (int i = 0;i < n;i++) {if (i == e - 1) continue;int ans = p[i] + g[i];//printf("%d\n", ans);res = max(res, ans);}printf("%d\n", res);}return 0;
}

16.消星星-1418

输出

对于每个样例,每行输出一个答案,表示消灭所有星星至少需要多少能量。

样例输入

2
2 2
ab
ba
3 3
aab
cab
ccb

样例输出

4
3

思路:dfs即可,遍历完直接就可以退出。

Memory: 2188K Time: 125MS
#include <stdio.h>
#include <string.h>
using namespace std;
char s[1001][1001];
int nums=0,n,m;
void dfs(int x,int y,char a)
{if(x>=n||x<0||y>=m||y<0||s[x][y]==0||s[x][y]!=a){return;}s[x][y]=0;nums++;dfs(x+1,y,a);dfs(x-1,y,a);dfs(x,y+1,a);dfs(x,y-1,a);
}
int main()
{int t;scanf("%d",&t);while(t--){memset(s,0,sizeof(s));nums=0;int res=0;scanf("%d%d",&n,&m);for(int i=0;i<n;i++){scanf("%s",s[i]);}for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(s[i][j]==0){continue;}if(nums==n*m){break;}dfs(i,j,s[i][j]);res++;}if(nums==n*m){//遍历全部即可退出break;}}printf("%d\n",res);}return 0;
}

17.1428-Train

样例输入

2
3 10 10
6 4 9
2 7 4
8 3 6
3 10 10
11 1 1
2 12 2
13 13 3

样例输出

10
0

思路:典型的背包dp问题,如果不明白的可以去搜索01背包 问题。

Memory: 1616K Time: 139MS
#include <iostream>
#include <string.h>
using namespace std;
typedef long long ll;
struct node
{ll v,x,w;
}res[1001];
ll dp[101][101];
int main()
{ll t;cin>>t;while(t--){ll n,m,s;cin>>n>>m>>s;for(ll i=1;i<=n;i++){cin>>res[i].v>>res[i].x>>res[i].w;}memset(dp,0,sizeof(dp));for(ll i=1;i<=n;i++){for(ll j=m;j>=res[i].v;j--){    //转移方程,要么装,要么不装,只有两种选择for(ll k=s;k>=res[i].x;k--){//不装那就是前一个状态,装就是前一个状态+现在状态if(j>=res[i].v&&k>=res[i].x){dp[j][k]=max(dp[j][k],dp[j-res[i].v][k-res[i].x]+res[i].w);}else{dp[j][k]=dp[j][k];}}}}cout<<dp[m][s]<<endl;}return 0;
}

18.1433-Swap Digits 不会......

19.1434-Lost Digits

样例输入

2
7?
?7

样例输出

2
1

思路:dp题,转移方程看我代码,这里不好敲。

Memory: 1532K Time: 15MS
#include <iostream>
#include <string.h>
using namespace std;int main()
{int t;cin>>t;while(t--){int dp[20][8];memset(dp,0,sizeof(dp));string s;cin>>s;int n=s.size();if(n==1&&s[0]=='?'){cout<<2<<endl;continue;}if(s[0]!='?'){dp[0][(s[0]-'0')%7]=1;}else{for(int i=0;i<10;i++){dp[0][i%7]++;}dp[0][0]--;}for(int i=1;i<=n;i++){if(s[i]=='?'){//如果是问号,那么对0-9都得做贡献for(int k=0;k<10;k++){for(int j=0;j<7;j++){dp[i][(10*j+k)%7]+=dp[i-1][j];//状态转移方程}}}else{for(int j=0;j<7;j++){//否则只对指定做贡献dp[i][(10*j+(s[i]-'0'))%7]+=dp[i-1][j];}}}cout<<dp[n-1][0]<<endl;}return 0;
}

20.1435-Path

样例输入

2
3 2 1
1 2 1
2 3 2
2
3 2 2
1 2 1
2 3 2
1 3

样例输出

3
1

思路:还是dijkstra算法,只不过要用超级原点,什么是超级原点呢?就是一个虚拟的点,要求他对所有起点的距离都是0,那么这样的话求出的距离不就是所有起点到终点的距离么?然后dijkstra算法就能求出最短的距离,也是很不错了。

Memory: 5372K Time: 874MS
#include <stdio.h>
#include <limits.h>
#include <algorithm>
#include <queue>
#include <string.h>
using namespace std;
typedef long long ll;
int s[1011][1011];
int d[1011];
int vis[1011];
int n,m,k;
struct node
{int a, b;bool operator<(const node&c)const{return b > c.b;}
};
void djstr(int k)
{fill(d, d + 1011, INT_MAX/2);priority_queue<node>q;while(k--){int a;scanf("%d",&a);d[a]=0;q.push((node){a,0});//所有点全部入栈,模拟超级原点,其他算法和dijkstra没有任何区别 }memset(vis, 0, sizeof(vis));while (!q.empty()) {node x = q.top();q.pop();int a = x.a;if (vis[a] == 1) {continue;}vis[a] = 1;for (int i = 1;i <= n;i++) {if (!vis[i] && s[a][i] < INT_MAX/2) {if (d[i] > d[a] + s[a][i]) {d[i] = d[a] + s[a][i];node temp;temp.a = i;temp.b = d[i];q.push(temp);}}}}
}
int main()
{int t;scanf("%d",&t);while(t--){fill(s[0],s[0]+1011*1011,INT_MAX/2);scanf("%d%d%d",&n,&m,&k);for(int i=0;i<m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);if(s[a][b]>c){s[a][b]=c;s[b][a]=c;}}djstr(k);ll res=0;for(int i=1;i<=n;i++){res+=(ll)d[i];}if(res>=INT_MAX/2){printf("-1\n");continue;}printf("%lld\n",res);}return 0;
}

2022-XTU程设练习3相关推荐

  1. E:魔兽世界三(开战) 2022春季程设实习

    描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部.两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 - N ( N <= 20).红魔军的司令部算作编号为0的城市, ...

  2. 航空航天大类C语言程设第三次练习赛

    航空航天大类C语言程设第三次练习赛 第四期更新, 鸽子博主终于更新第三次练习赛了 (A题)求区间交并集 多行数据,每行有两个数,用空格分开,表示每个区间的下和上界,保证是合法的非空集,而且得到的并集是 ...

  3. BUAA程设第四周上机总结

    BUAA程设第四周上机总结 代码格式化 基本输入输出 输入 scanf的小技巧 注意事项 关于字符串读入 输出 printf格式控制符的操作 标识变量的使用 代码格式化 同学们的码风可能一时半会不好培 ...

  4. BUAA程设第五周总结

    BUAA程设第五周总结 自定义函数的注意事项 不要和已有的函数重名 函数只能返回一个值 注意使用函数过程中发生的隐式类型转换 使用各种方法替代define 使用const全局变量 使用typedef ...

  5. 让技术被看见——2022携程技术极客文化节

    提到携程技术,你会想到什么? 提到携程技术人呢,你又会想到什么? 很多时候,技术扮演着业务发展背后的支撑和引擎的角色:同样,技术人,也往往隐藏在一行行代码背后,来和用户沟通和交流. 今天,借着1024 ...

  6. 程设刷题 | 程序设计实践II-2017(部分)

    目录 1165-算术题 题目描述 代码实现 1184-Tourist 1 题目描述 代码实现 1186-Tourist 2 题目描述 代码实现 1224-LOVE 题目描述 代码实现 1256-湘潭大 ...

  7. 北大程设 魔兽终极版总结

    几个坑: 1.已经走到对方基地但是此时还没有赢的武士,仍需要报告工作 2.dragon的yell条件是自己没有死(对方是被弓射死会yell) 3.在有敌人的城市被射死会影响旗帜更换 4.奖励,获得生命 ...

  8. C++程设实验项目三:黑白棋与基于UCT算法的AI

    在这篇博客里,我将总结一下在这次实验中学到的UCT算法实现原理. 首先是参考文章: https://blog.csdn.net/u014397729/article/details/27366363 ...

  9. CVPR 2022 | 南开程明明团队和天大提出LD:目标检测的定位蒸馏

    作者:Jin.Carlo  |  已授权转载(源:知乎)编辑:CVer https://zhuanlan.zhihu.com/p/474955539 先上我们文章和代码: Localization D ...

最新文章

  1. 为什么尽量避免使用 CSS 表达式
  2. 优质的网站结构设计有哪些好处?
  3. 图像中添加二项式分布噪声
  4. 简单几步教你去除开机出现扫描硬盘!
  5. kotlin学习笔记——集合及集合操作符
  6. ubuntu安装 ftpd server(vsftpd)
  7. DrawTool画笔之图形笔
  8. JVM 垃圾回收算法机制及其实现原理
  9. Redis简介、安装、配置、启用学习笔记
  10. Error parsing YAML config file: yaml-cpp: error at line
  11. 大数据导论章节答案_智慧树APP大数据导论第三单元章节测试答案
  12. python课设参考文献_Python课程设计任务书
  13. python 柱状图和折线图放在一起_python中用matplotlib画折线图、柱状图、散点图
  14. 刷屏专用超长复制_求超长的刷屏文字
  15. HTML——使用表格制作个人简历
  16. DLNA使用设置教程
  17. 百度-还可以这样玩!
  18. python编辑svg文件_使用Python创建SVG
  19. “搜索大战”正式打响,微软发布ChatGPT版搜索引擎和浏览器
  20. 水果店促销方案,水果店开业怎么搞促销

热门文章

  1. RISC-V共建 | openKylin与深度数智战略合作会议召开
  2. 随便写写,都是我从网上收集的东西!
  3. OpenGL粒子系统和变换反馈
  4. winaip文档服务器打印,使用 Win32 API 将原始数据发送到打印机
  5. 网页制作工具哪款软件最好?
  6. (一)物联网云平台--阿里云--创建属于自己的产品和设备
  7. 压铸模具计算机台吨位公式,如何根据产品计算压铸机吨位
  8. 黑叔推荐:6个上班摸鱼的网址!
  9. 学计算机pr学的好有用吗,别人用手机剪映剪辑出来的视频,比我用电脑pr剪辑的还要好?瞬间被打击了,我学习了pr还有什么优势吗?_科技数码通...
  10. 系统文件夹合并在一起怎么办?