Codeforces Round #346 (Div. 2)
题意:长度为n个环、起始位置是a,然后给出b,b是正数代表顺时针跑b个单位、b是负数代表逆时针跑b个单位、
思路:基础数学题目吧、
PS:对于C++和G++编译器而言 比如-7%3的结果是-1、但在数学中是2、 这题所要的结果是在数学中的、
1 #include<cmath> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 int main() 7 { 8 int n,a,b; 9 scanf("%d%d%d",&n,&a,&b); 10 int ans=(a+b)%n; 11 if(ans<=0) ans+=n; 12 printf("%d\n",ans); 13 return 0; 14 }
题意:就说一个国家要举办区域赛、有m个地区、每个地区至少有两只得分不同的队伍,一共有n个队伍参赛,求出每个地区(从1地区输出到m地区)选出两个队伍出来、要求这两个队伍在他所属的地区中排名前两位、排名按得分来排、如果一个地区有多种选择那么就输出‘?’,否则输出选出的两只队伍、
思路:先按地区排序然后地区相同按得分来排、然后一个地区一个地区的扫、对于每个地区能选出队伍的情况就两种、一种是当前地区的最高分恰好只有两个、另外一种是最高分一个第二高分一个、 其他情况均不符合、在扫的时候记录一下最高分和次高分的位置就可以了、
1 #include<cmath> 2 #include<cstring> 3 #include<cstdio> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 struct Team 8 { 9 string name; 10 int id; 11 int score; 12 string reve; 13 bool operator < (Team a) 14 { 15 if(id==a.id) return score>a.score; 16 return id<a.id; 17 } 18 }team[100005]; 19 string chong[100005]; 20 int n,m; 21 int main() 22 { 23 cin >> n >> m; 24 for(int i=0;i<n;++i){ 25 cin >> team[i].name >> team[i].id >> team[i].score; 26 for(int i=0;i<team[i].name.size();++i) 27 team[i].reve+=tolower(team[i].name[i]); 28 } 29 int k=0; 30 sort(team,team+n); 31 for(int i=0;i<n;++i){ 32 int a,b,qa,qb,j,sa,sb; // a b用来记录当前地区最高分和次高分、 33 qa=qb=0; // qa qb 用来记录最高分和次高分出现的次数、 34 a=b=-1; // sa sb 记录的是最高分和次高分第一次出现的位置、 35 for(j=i;j<n;++j){ 36 if(team[j].id!=team[i].id) break; //不属于当前地区的话就退出循环、 37 if(a==-1) a=team[j].score,sa=j,qa=1; 38 else if(a==team[j].score) qa++; 39 else if(b==-1) b=team[j].score,sb=j,qb=1; 40 else if(b==team[j].score) qb++; 41 } 42 if(qa==2) 43 cout << team[sa].name << " " << team[sa+1].name << endl; 44 else if(qa==1&&qb==1) 45 cout << team[sa].name << " " << team[sb].name << endl; 46 else cout << "?" << endl; 47 i+=(j-i-1); //分界点要注意一下、 48 } 49 return 0; 50 }
PS:这题我自己踩到自己的坑了、 就是在a,b赋值的时候我是直接为0并且在寻找最高分和次高分的时候判断是否等于0、等于0就代表当前没有最高分和最高分、
如果有两个队伍分数恰好为0、那我判断就与我设想的不一样了、 所以被WA在51组数据、提醒一下自己把、 在设置判断变量的时候一定要设置为不可能的值、
题意:给出n个物品每个物品有一个数值、每个不一样的数值代表一种类型的物品、现在给出一个容量m、要你求出最多能买多少类型不同的物品、举个样例吧、
3 7
1 3 4 输出是2 5 就是说买下物品2的话容量还剩下 7 - 2 = 5、 但是 3 和 4又存在、 所以直接向后枚举咯、
思路:用map记录已经存在的物品、然后从1枚举到m(基于贪心的思想,因为要求最多还能买下多少物品)、 如果物品不存在就购买、然后容量减少、
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<map> 6 using namespace std; 7 int n,m,x; 8 int num[100005]; 9 int main() 10 { 11 map<int,int>q; 12 scanf("%d%d",&n,&m); 13 for(int i=0;i<n;++i){ 14 scanf("%d",&x); 15 q[x]++; 16 } 17 18 sort(num,num+n); 19 int sum=0; 20 int ans=m; 21 for(int i=1;i<=ans;++i){ 22 if(q[i]>0) continue; 23 if(m-i<0) break; 24 num[sum++]=i; 25 m-=i; 26 } 27 printf("%d\n",sum); 28 for(int i=0;i<sum;++i) 29 if(i==0) printf("%d",num[i]); 30 else printf(" %d",num[i]); 31 printf("\n"); 32 return 0; 33 }
题意:给出一个图、原来是无向图、现在要你改成有向图、是入度为0的点尽可能小、并输出入度为0的点的个数、
思路:想通了其实就是想办法判环、 如果是环那么整个环的贡献就是0、否则每一个连通块的贡献就是1
我这里写了一个dfs判环的思路、感觉不是很好呀、
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 #define mst(ss,b) memset(ss,b,sizeof(ss)) 6 using namespace std; 7 const int qq=200100; //要注意一下数据范围、因为是开的无向图、 8 int n,m; 9 int head[qq],vis[qq],top; 10 struct Edge{ 11 int v,next; 12 }edge[qq]; 13 void init() 14 { 15 mst(head,-1); 16 top=0; 17 mst(vis,0); 18 } 19 void Add(int u,int v) 20 { 21 edge[top].v=v; 22 edge[top].next=head[u]; 23 head[u]=top++; 24 } 25 int ans=0,flag; 26 void dfs(int u,int pre) 27 { 28 for(int i=head[u];i!=-1;i=edge[i].next){ 29 int v=edge[i].v; 30 if(v==pre) continue; 31 if(!vis[v]){ 32 vis[v]=1; 33 dfs(v,u); 34 } 35 else flag=1; //如果已经访问到了已经访问过的点、那么就有环了 36 } 37 } 38 void solve() 39 { 40 for(int i=1;i<=n;++i){ 41 flag=0; 42 if(!vis[i]){ 43 vis[i]=1; 44 dfs(i,0); 45 if(flag==0) ans++; 46 } 47 } 48 cout << ans << endl; 49 } 50 int main() 51 { 52 init(); 53 scanf("%d%d",&n,&m); 54 for(int i=1;i<=m;++i){ 55 int u,v; 56 scanf("%d%d",&u,&v); 57 Add(u,v); 58 Add(v,u); 59 } 60 solve(); 61 return 0; 62 }
在codeforces上找了一个大牛的代码、也差不多是dfs但是判断环的条件和我这个不一样、感觉很好理解阿
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int n,m,x,y,vis[100005],re,edg,co; 5 vector< vector<int> > adj; 6 7 void dfs(int u){ 8 vis[u]=1;co++; 9 for(int j=0;j<adj[u].size();j++){ 10 int v=adj[u][j];edg++; 11 if(!vis[v]) dfs(v); 12 } 13 } 14 15 int main(){ 16 cin>>n>>m;re=0; 17 adj.assign(n,vector<int>(0)); 18 for(int i=0;i<m;i++){ 19 cin>>x>>y; 20 x--;y--; 21 adj[x].push_back(y);adj[y].push_back(x); 22 } 23 for(int i=0;i<n;i++){ 24 if(!vis[i]){ 25 edg=co=0;dfs(i); 26 edg/=2; 27 if(edg==co-1) re++; 28 } 29 } 30 cout<<re<<endl; 31 return 0; 32 }