当前位置:   article > 正文

【ZZULIOJ】ZZULI-2019年3月份月赛(个人赛)_zzuli二元组

zzuli二元组

A.异或运算的基础题,但是很多人排序就过啦~~~

题解:

首先,变量元素对所有元素进行异或操作,得到的结果肯定是an^am。也就说通过异或操作以后,结果中保存了an和am的特征。由于am和an不同,am^an的结果肯定是大于等于1。am和an不同,那么am^an中为1的某一个bit肯定是am或者an中某一个的特征。

   然后,定义两个值num1,num2,分别用来计算an、am,选择am^an中的某一个bit作为特征位,假设是第K位是特征位,再次对元素进行遍历,如果元素的第K位是1,这个元素可能是am或者an,那么将当前元素与num1进行异或操作,如果元素的第K为不为0,那么这个元素则可能是另一个值,那么将当前元素与num2进行异或操作。这样遍历完所有元素,因为大部分数据成对出现,根据异或运算的特征,num1,num2就分别保存了两个不同的值。
 

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define getbit(x,y) ((x) >> (y)&1)//取出x的第y位
  4. int a[40],b[40];
  5. int main()
  6. {
  7. int n,k;
  8. cin>>n>>k;
  9. if(k==1)//一个特殊数,直接异或即可
  10. {
  11. long long int ans,temp;
  12. for(int i=0;i<n;i++)
  13. {
  14. scanf("%lld",&temp);
  15. if(i==0)
  16. {
  17. ans=temp;
  18. }
  19. else
  20. {
  21. ans^=temp;
  22. }
  23. }
  24. cout<<ans<<endl;
  25. }
  26. else
  27. {
  28. long long int ans,temp;
  29. for(int i=0;i<n;i++)//两个特殊数的时候,把每个数化成二进制, 第y位为1的时候,与a[]异或,否则与b[]异或
  30. {
  31. scanf("%lld",&temp);
  32. for(int j=0;j<31;j++)
  33. {
  34. if(getbit(temp,j))
  35. {
  36. a[j]^=temp;
  37. }
  38. else
  39. {
  40. b[j]^=temp;
  41. }
  42. }
  43. if(i==0)
  44. {
  45. ans=temp;
  46. }
  47. else
  48. {
  49. ans^=temp;
  50. }
  51. }
  52. for(int j=0;j<31;j++)
  53. {
  54. if(getbit(ans,j))
  55. {
  56. cout<<min(a[j],b[j])<<' '<<max(a[j],b[j])<<endl;//从小到大输出
  57. break;
  58. }
  59. }
  60. }
  61. return 0;
  62. }

B.签到题

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main()
  4. {
  5. long long int a;
  6. cin>>a;
  7. int g=0,s=0,b=0;
  8. b=a/10;
  9. s=a%10/5;
  10. g=a%10%5;
  11. cout<<b<<' '<<s<<' '<<g<<endl;
  12. return 0;
  13. }

I.签到题

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. long long int a[1000000+10];
  4. int main()
  5. {
  6. long long int k;
  7. cin>>k;
  8. a[1]=1;
  9. a[2]=1;
  10. for(int i=3;i<=1000000;i++)
  11. {
  12. a[i]=(a[i-2]*a[i-2]+a[i-1]*(i-1))%i;
  13. }
  14. cout<<a[k]<<endl;
  15. return 0;
  16. }

G.统计字符出现的个数,相除后最小的记为答案。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. char s[10000+10];
  4. char p[100];
  5. int a[30],b[30];
  6. int main()
  7. {
  8. cin>>s>>p;
  9. int slen=strlen(s);
  10. for(int i=0;i<slen;i++)
  11. {
  12. if(s[i]>='a'&&s[i]<='z')
  13. {
  14. a[s[i]-'a']++;
  15. }
  16. if(s[i]>='A'&&s[i]<='Z')
  17. {
  18. a[s[i]-'A']++;
  19. }
  20. }
  21. int plen=strlen(p);
  22. for(int i=0;i<plen;i++)
  23. {
  24. if(p[i]>='a'&&p[i]<='z')
  25. {
  26. b[p[i]-'a']++;
  27. }
  28. if(p[i]>='A'&&p[i]<='Z')
  29. {
  30. b[p[i]-'A']++;
  31. }
  32. }
  33. int ans=99999;
  34. for(int i=0;i<26;i++)
  35. {
  36. if(b[i]!=0&&a[i]/b[i]<ans)
  37. {
  38. ans=a[i]/b[i];
  39. }
  40. }
  41. cout<<ans<<endl;
  42. return 0;
  43. }

H.最短路,注意重边,无向图。

djk的解法

  1. /*
  2. 时间复杂度:O(n2)点的数量
  3. */
  4. #include<bits/stdc++.h>
  5. using namespace std;
  6. #define MAX 3000
  7. #define inf 2147483647
  8. long long int d[MAX];//结点i的路径长度为d[i]
  9. long long int v[MAX];//标记是否使用过该点
  10. long long int w[MAX][MAX];//记录两点之间的花费
  11. long long int start=0,n,m,en;//起始点begin 点n表示点的数量 m表示边的数量
  12. long long int fa[MAX];//维护父亲结点,用来找路径
  13. void init()//初始化
  14. {
  15. for(int i=1;i<=n;i++)//把起点之外的点的距离设为inf,起点的距离设为0
  16. {
  17. d[i]=(i==start ? 0:inf);
  18. }
  19. memset(v,0,sizeof(v));//全部为未使用 0:未使用 1:使用
  20. for(int i=1;i<=n;i++)
  21. for(int j=1;j<=n;j++)
  22. w[i][j]=inf;
  23. }
  24. void Dijkstra()
  25. {
  26. for(int i=1;i<=n;i++)
  27. {
  28. int pos,Min=inf;
  29. for(int j=1;j<=n;j++)//未标记的结点中,结点d[j]值最小的点 pos
  30. {
  31. if(!v[j]&&d[j]<=Min)
  32. {
  33. Min=d[j];
  34. pos=j;
  35. }
  36. }
  37. v[pos]=1;//标记最小结点 pos
  38. for(int j=1;j<=n;j++)//对于从pos出发的所有边(pos,j),更新 d[j]=min(d[j],d[pos]+w[pos][j])
  39. {
  40. //d[j]=min(d[j],d[pos]+w[pos][j]);
  41. if(d[j]>d[pos]+w[pos][j])
  42. {
  43. d[j]=d[pos]+w[pos][j];
  44. fa[j]=pos;
  45. }
  46. }
  47. }
  48. }
  49. int main()
  50. {
  51. scanf("%lld%lld%lld%lld",&n,&m,&start,&en);
  52. init();
  53. for(int i=0;i<m;i++)
  54. {
  55. long long int a,b,c;
  56. scanf("%lld%lld%lld",&a,&b,&c);
  57. //无向图
  58. if(w[a][b]>c)
  59. {
  60. w[a][b]=c;
  61. w[b][a]=c;
  62. }
  63. }
  64. Dijkstra();
  65. printf("%lld\n",d[en]);
  66. return 0;
  67. }

 

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号