CSP2014-03
CSP201403-1 相反数
水题
1 // 2 // main.cpp 3 // CSP201403-1 相反数 4 // 5 // Created by sylvia on 2021/10/13. 6 // Copyright © 2021 apple. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <math.h> 13 #include <string.h> 14 #include <algorithm> 15 16 using namespace std; 17 #define MAX 1000+5 18 #define LL long long 19 #define MOD 1000000007 20 int n; 21 LL ans; 22 int tmp,k; 23 int f[MAX]; 24 int main(){ 25 cin>>n; 26 memset(f,0,sizeof(f)); 27 register int i,j; 28 for (i=1;i<=n;++i){ 29 cin>>tmp; 30 k=++f[abs(tmp)]; 31 if(k==2) ++ans; 32 } 33 cout<<ans<<endl; 34 return 0; 35 }
CSP201403-2 窗口
大水题
1 // 2 // main.cpp 3 // CSP201403-2 窗口 4 // 5 // Created by sylvia on 2021/10/14. 6 // Copyright © 2021 apple. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <math.h> 13 #include <string.h> 14 #include <algorithm> 15 16 using namespace std; 17 #define MAX 10+5 18 #define LL long long 19 int n,m; 20 struct TYPE{ 21 int x1,x2,y1,y2,weight=0; 22 }a[MAX]; 23 int x,y; 24 25 int main(){ 26 register int i,j; 27 scanf("%d%d",&n,&m); 28 for (i=1;i<=n;++i){ 29 scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2); 30 a[i].weight=i; 31 } 32 for (i=1;i<=m;++i){ 33 scanf("%d%d",&x,&y); 34 int tmpw=-1,tmpj; 35 for(j=1;j<=n;++j){ 36 if (x<=a[j].x2&&x>=a[j].x1&&y<=a[j].y2&&y>=a[j].y1){ 37 if(a[j].weight>tmpw){ 38 tmpw=a[j].weight; 39 tmpj=j; 40 } 41 } 42 } 43 if(tmpw==-1) cout<<"IGNORED"<<endl; 44 else { 45 cout<<tmpj<<endl; 46 a[tmpj].weight=i+n; 47 } 48 } 49 return 0; 50 }
CSP201403-3 命令行选项
❤️累了……真的心累,一个超级大模拟,甚至大也够不上……,我做了两个多小时,辣鸡!就是停留在90分上,不知道到底是缺少判断了什么条件,数组我开的足够大了。。。边界我已经一而再再而三的考虑了就是过不了,那就算了……模拟题不知道我费心乏力害
总结一下字符串/字符的读入情况吧,总是在读入上吃亏……
1.整行读入,忽略空格
1⃣️cin.getline(str,length);
第一个参数为字符串,第二个参数为指定的最大长度
str为字符数组类型
#include <iostream> using namespace std; char str[20]; cin.getline(str, 20);
2⃣️getline(cin,str)
str必须为string类型
#include <string> using namespace std; string s; getline(cin, s);
3⃣️scanf("%[^\n]",str);
#include <stdio.h> void main() { char str[100]; scanf("%[^\n]",str); }
4⃣️gets(str)
不安全,一般不再使用
2.空格结束
scanf(“%s”,str);
cin>>str;
需要配合getchar()使用
1 // 90分代码 2 // main.cpp 3 // CSP201403-3 命令行选项 4 // 5 // Created by sylvia on 2021/10/15. 6 // Copyright © 2021 apple. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <math.h> 13 #include <string.h> 14 #include <algorithm> 15 #include <string> 16 //命令行工具名(小写) 若干参数和选项 17 //选项:带参数 参数:小写字母、数字、减号组成 18 //无参数 -小写字母。-a 19 20 using namespace std; 21 #define MAXN 256+2 22 pair<int,int> a[MAXN]; //first 是否为选项。second 是否有参数 23 pair<int,char[MAXN]> num[MAXN]; 24 int n; 25 char s[MAXN],ss[MAXN]; 26 char temps[MAXN]; 27 int len,t; 28 29 int main(){ 30 memset(a,0,sizeof(a)); 31 register int i,j,k; 32 scanf("%s",s); 33 len=strlen(s); 34 for (i=0;i<len;i++){ 35 if(s[i]>='a'&&s[i]<='z'){ 36 a[s[i]-'a'].first=1; 37 if(s[i+1]==':') a[s[i]-'a'].second=1; 38 } 39 } 40 scanf("%d\n",&n); 41 for (i=1;i<=n;++i){ 42 cin.getline(temps,MAXN); 43 memset(num,0,sizeof(num)); 44 len=strlen(temps); 45 int j=0; 46 while(temps[j]!=' '&&j<len){ 47 j++; 48 } 49 if(j<len-1) j++; 50 int flag=1; 51 while(j<len&&flag){ 52 if(temps[j]=='-'){ 53 j++; 54 int tempp=temps[j]-'a'; 55 if(a[tempp].first){ 56 num[tempp].first++; 57 if(a[tempp].second){ 58 j+=2; 59 if(j==len-1) num[tempp].first--; 60 strcpy(ss,""); 61 while(temps[j]!=' '&&j<len&&flag){ 62 if(!((temps[j]<='z'&&temps[j]>='a')||(temps[j]>='0'&&temps[j]<='9')||temps[j]=='-')) { 63 j=len; 64 flag=0; 65 break; 66 } 67 strncat(ss,temps+j,1); 68 j++; 69 } 70 if(flag) strcpy(num[tempp].second,ss); 71 j+=1; 72 } 73 else{ 74 if(temps[j+2]!='-'){ 75 j=len; 76 flag=0; 77 78 } else j+=2; 79 } 80 } 81 else { 82 flag=0; 83 j=len; 84 } 85 } 86 else {flag=0;} 87 88 } 89 printf("Case %d:",i); 90 for(k=0;k<26;k++){ 91 if(num[k].first){ 92 printf(" -%c",k+'a'); 93 if(a[k].second){ 94 printf(" %s",num[k].second); 95 96 } 97 } 98 } 99 printf("\n"); 100 } 101 return 0; 102 }
CSP201403-4 无线网络
典型最短路算法
1.首先上Floyed60分做法,主要还是ccf的数据太水了,完全没有去判断K这个条件,就裸Floyed都能拿60,剩下的是超时,主要还是为了回忆一下最短路算法,所以用这个写了,当然不会是正解
1 // 2 // main.cpp 3 // CSP201403-4 无线网络 v1-Floyed-60‘ 4 // 5 // Created by sylvia on 2021/10/19. 6 // Copyright © 2021 apple. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <algorithm> 11 #include <stdio.h> 12 #include <string.h> 13 #include <math.h> 14 15 using namespace std; 16 #define LL long long 17 #define MAX 100+2 18 #define INF 1e8+2 19 20 int n,m,k; 21 pair <LL,LL> a[MAX*2]; 22 LL r; 23 LL e[MAX*2][MAX*2]; 24 //spfa、djs、floyed、dfs 25 inline int judge(LL x1,LL y1,LL x2,LL y2){ 26 LL temp=ceil(sqrt(pow(abs(x1-x2),2)+pow(abs(y1-y2),2))); 27 if(temp>r) return 0; 28 else return 1; 29 } 30 31 int main(){ 32 memset(e,0,sizeof(e)); 33 scanf("%d%d%d%lld",&n,&m,&k,&r); 34 for(int i=1;i<=n+m;i++){ 35 scanf("%lld%lld",&a[i].first,&a[i].second); 36 } 37 for (register int i=1;i<=n+m;i++){ 38 for (register int j=i+1;j<=n+m;j++){ 39 if(judge(a[i].first,a[i].second,a[j].first,a[j].second)) 40 e[i][j]=e[j][i]=1; 41 else e[i][j]=e[j][i]=INF; 42 43 } 44 } 45 for (register int i=1;i<=n+m;i++){ 46 for (register int j=1;j<=n+m;j++){ 47 for (register int k=1;k<=n+m;k++){ 48 if(e[j][k]>e[j][i]+e[i][k]) e[j][k]=e[j][i]+e[i][k]; 49 } 50 } 51 } 52 printf("%lld\n",e[1][2]-1); 53 return 0; 54 }
2.然后用Dijkstra写了,虽然不是全裸的,但半裸也算得上了……
主要是在k这个限制上,使用cnt数组记录到达当前节点经过了多少个新增节点,更新的时候注意如果超过了K则不更新……说实话写完之后我总觉得还有点bug……但他过了……
然后学习了一下容器的使用,果然是好登西
fill(a,a+n,INF); //fill进行初始化,不限定于0,-1等数值,定义在<algorithm>中
vector<int> a;//定义容器变量,定义在<vector>中
a.push_back(4);// 在容器尾部插入元素
a.size();//获取容器长度(元素个数)
1 // 2 // main.cpp 3 // CSP201403-4 无线网络 v2-Dijkstra-100‘ 4 // 5 // Created by sylvia on 2021/10/19. 6 // Copyright © 2021 apple. All rights reserved. 7 // 8 #include <stdio.h> 9 #include <string.h> 10 #include <algorithm> 11 #include <vector> 12 #include <cmath> 13 #include <stdlib.h> 14 15 using namespace std; 16 #define MAX 200+5 17 #define INF 1e8+2 18 #define LL long long 19 20 struct Info 21 { 22 LL x,y; 23 }point[MAX]; 24 vector<int> adj[MAX]; 25 26 int vis[MAX]; 27 int num[MAX]; 28 int cnt[MAX]; 29 30 //num数组来记录沿途经过的总路由器个数/或路径长度 31 //cnt数组来记录沿途讲过的新增路由器个数 32 int Dijkstra(int s,int n,int m,int k) 33 { 34 fill(vis,vis+MAX,0); 35 fill(num,num+MAX,INF); 36 fill(cnt,cnt+MAX,0); 37 num[s]=0; 38 int j; 39 while(1) 40 { 41 int u=-1; 42 int mini=INF; 43 for(j=0;j<m+n;j++) //找离S中顶点最近的U中的一个顶点加入S中 44 { 45 if(vis[j]==0&&num[j]<mini) 46 { 47 u=j; 48 mini=num[j]; 49 } 50 } 51 if(u==-1) break; //遍历完成 52 vis[u]=1; //加入S中 53 for(int j=0;j<adj[u].size();j++) 54 { 55 int v=adj[u][j]; 56 if(vis[v]==0&&num[u]+1<num[v]) //每次更新的时候,都用途径路由器的最小个数进行更新 57 { 58 if(v<n) //如果当前要更新前面n个固定路由器的信息,则直接更新相关信息 59 { 60 num[v]=num[u]+1; 61 cnt[v]=cnt[u]; 62 } 63 else //如果当前要更新的是后面m个新增路由器的信息,那么就要考虑是否 64 //能够将该新增路由器加入到线路当中,因此需要引入限制条件 65 { 66 if(cnt[u]+1<=k) 67 { 68 cnt[v]=cnt[u]+1; 69 num[v]=num[u]+1; 70 } 71 } 72 } 73 } 74 } 75 return num[1]-1; 76 } 77 78 int main() 79 { 80 int n,m,k; 81 LL r; 82 int i,j; 83 scanf("%d %d %d %lld",&n,&m,&k,&r); 84 for(i=0;i<n+m;i++) 85 scanf("%lld %lld",&point[i].x,&point[i].y); 86 //建图 87 for(i=0;i<n+m;i++) 88 for(j=i+1;j<n+m;j++) 89 { 90 91 LL temp=ceil(sqrt((pow(point[i].x-point[j].x,2)+pow(point[i].y-point[j].y,2)))); 92 if(temp<=r) 93 { 94 adj[i].push_back(j); 95 adj[j].push_back(i); 96 } 97 } 98 printf("%d\n",Dijkstra(0,n,m,k)); 99 return 0; 100 }
3.还可以用spfa……,这不是我写的
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 #include <memory.h> 5 #include <queue> 6 #include <fstream> 7 8 using namespace std; 9 10 typedef long long LL; 11 12 class Point 13 { 14 public: 15 int x; 16 int y; 17 18 Point(int x = 0, int y = 0) :x(x), y(y){}; 19 }; 20 21 class Dist 22 { 23 public: 24 int i; 25 int k; 26 Dist(int i = 0, int k = 0) :i(i), k(k){}; 27 }; 28 29 const int inf = 0x3f3f3f3f; 30 const int maxn = 205; 31 32 bool adj[maxn][maxn]; 33 int ds[maxn][maxn]; 34 bool vis[maxn][maxn]; 35 36 int n, m, k, r; 37 38 void spfa() 39 { 40 queue<Dist> q; 41 q.push(Dist(0, 0)); 42 vis[0][0] = true; 43 ds[0][0] = 0; 44 int tmpk = 0; 45 Dist d; 46 while (!q.empty()) 47 { 48 d = q.front(); 49 q.pop(); 50 vis[d.i][d.k] = false; 51 for (int j = 0; j < n + m; j++) 52 { 53 tmpk = d.k; 54 if (adj[d.i][j]) 55 { 56 if (j >= n) 57 ++tmpk; 58 if (tmpk <= k && ds[j][tmpk] > ds[d.i][d.k] + 1) 59 { 60 ds[j][tmpk] = ds[d.i][d.k] + 1; 61 if (!vis[j][tmpk]) 62 { 63 q.push(Dist(j, tmpk)); 64 vis[j][tmpk] = true; 65 } 66 67 } 68 } 69 } 70 71 } 72 } 73 74 75 int main() 76 { 77 //ifstream cin("a.txt"); 78 memset(adj, false, sizeof(adj)); 79 memset(vis, false, sizeof(vis)); 80 memset(ds, inf, sizeof(ds)); 81 82 cin >> n >> m >> k >> r; 83 vector<Point> pts; 84 int x, y; 85 for (int i = 0; i < n + m; i++) 86 { 87 cin >> x >> y; 88 pts.push_back(Point(x, y)); 89 } 90 LL a, b; 91 for (int i = 0; i < pts.size(); i++) 92 { 93 for (int j = 0; j < pts.size(); j++) 94 { 95 a = pts[i].x - pts[j].x; 96 b = pts[i].y - pts[j].y; 97 if ((a * a + b * b <= (LL)r * r)) 98 adj[i][j] = true; 99 } 100 } 101 spfa(); 102 103 int ans = inf; 104 for (int i = 0; i <= k; i++) 105 ans = min(ans, ds[1][i]); 106 cout << ans - 1 << endl; 107 //cin.close(); 108 return 0; 109 }
4.由于路径都是1,所以最简单的还是用bfs
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 using namespace std; 5 6 const int maxn = 205; 7 long long n, m, k, r, max1=-1; 8 bool visit[maxn] = {};//默认值为false,确保刚开始每个节点都没有被走过 9 10 struct node { 11 long long x, y, k; 12 int step; 13 node () { step = k = 0; }//默认k=0 14 node (int x1, int y1, int s1, int k1) {x=x1;y=y1;step=s1;k=k1;}//有参构造函数 15 } map[maxn];//用来记录每个节点的信息 16 17 18 19 int bfs(int begin, int end)//利用深度优先算法遍历来计算起点到终点 20 { 21 queue<node> Q; 22 Q.push(node(map[begin].x, map[begin].y, 0, 0));//起始点入站 23 visit[begin] = true;//true说明该节点已经走过来,避免重复节点 24 25 26 while (!Q.empty()) 27 { 28 node s = Q.front(); 29 Q.pop();//入栈 30 31 if (s.x == map[end].x && s.y == map[end].y) return s.step - 1;//求出中转个数 32 if (s.k == k) max1=n; // 当前k值一旦到达k时只能在n里面走,不能用map[n]之外的节点了 33 else max1=n+m;//当前k值小于原k时就可以在map[n+m]里面走 34 35 36 37 for (int i=1;i<= max1;++i) 38 { 39 if (visit[i]) continue;//已经走过就不走了 40 if ((map[i].x - s.x)*(map[i].x - s.x) + (map[i].y - s.y)*(map[i].y - s.y) > r*r) continue;//距离不够就不走 41 42 43 visit[i] = true; //距离够了就开始准备走 44 45 int kk; 46 if(i>n)kk=s.k+1; 47 else kk=s.k;//根据当前节点的类型决定是否加k值 48 49 Q.push(node(map[i].x, map[i].y, s.step + 1, kk));//走进去,放进队列中 50 } 51 } 52 } 53 54 55 56 int main() 57 { 58 cin >> n >> m >> k >> r; 59 for (int i = 1; i <= n + m; ++i) 60 { 61 cin >> map[i].x >> map[i].y; 62 }//初始化输入 63 64 cout << bfs(1, 2);//输入结果 65 }