奋斗群群赛7总结与心得

来源:互联网 发布:中宏统计数据库 编辑:程序博客网 时间:2024/05/04 11:04

  • 总体情况
  • T1
    • 题目
    • 思路
  • T2
    • 题目
    • 思路
  • T3
    • 题目
    • 思路
  • T4
    • 题目
    • 思路
  • T5
    • 题目
    • 思路

总体情况

https://vjudge.net/contest/184260
本次人品很好,老师发了一次福利,五道题都很水(我应该没有资格说这种话吧).

T1

题目

对于一个大于1的正整数,输出它最多能被分解成多少个质数之和,以及这些质数.

思路

明显的水题吧.对于偶数,全部输出2;对于奇数,输出很多2加上一个3就可以了.

#include<bits/stdc++.h>using namespace std;int main(){int n,t,i;cin>>n;cout<<n/2<<endl;if (n%2!=0)   {  for (i=1;i<=n/2-1;i++) cout<<2<<" ";  cout<<3;  }else for (i=1;i<=n/2;i++) cout<<2<<" ";}

T2

题目

在平面直角坐标系中知道平行四边形三个顶点的坐标,求剩下一个顶点的坐标的所有可能情况.

思路

应该是初中数学的一个公式,肯定有3种可能.直接套就可以了.

#include<bits/stdc++.h>using namespace std;int main(){int x1,y1,x2,y2,x3,y3;cin>>x1>>y1>>x2>>y2>>x3>>y3;cout<<3<<endl;cout<<x1+x3-x2<<" "<<y1+y3-y2<<endl;cout<<x2+x3-x1<<" "<<y2+y3-y1<<endl;cout<<x1+x2-x3<<" "<<y1+y2-y3<<endl;}

T3

题目

在一次投票中,所有选民分成D,R两派,从第一个人开始不断循环投票.所谓投票就是他可以把对方的一个人给踢掉,让他不能投票.最后只剩下了一个人可以投票,输出他的党派.

思路

我想的是暴枚.每次扫一个,如果是D就把字符串里第一个R删掉,反之亦然.一直这样下去,最后只剩下了一个.这个方法比较复杂,在第12个点T了.

#include<bits/stdc++.h>using namespace std;string s;int main(){int n,i,d=0,r=0;cin>>n>>s;for (i=0;i<n;i++)   {  if (s[i]=='D') d++;  else if (s[i]=='R') r++;  }i=0;while (d>0&&r>0)//场上两派人都有  {  if (s[i]=='D')     {    r--;    int t=s.find('R');//找到第一个R    if (t>=0&&t<n) s[t]='G';//删掉它,这里是让他变成G    }  else if (s[i]=='R')    {    d--;    int t=s.find('D');    if (t>=0&&t<n) s[t]='G';    }   i++;    if (i==n) i=0;//循环吧  }if (d==0) cout<<"R";else cout<<"D";}

这样不行,我从CF上借鉴了一个代码下来.我用我的代码风格打了一遍,同时我也讲一下它的思考方法.既然轮到我投票的时候我可以踢掉对方一个人,那我可以变成让我方加一个人啊.

#include<bits/stdc++.h>using namespace std;int main(){int n,i,r=0,d=0;string s;cin>>n>>s;for (i=0;i<2*n;i++)   {  if (s[i]=='D')    {    d++,r--;    if (r<0) s+='D';//r<0,说明此时d正在把r的人踢掉,当后面r反过来踢d的时候,按原来的规则他的发言是无效的,所以当d>0的时候出现R是不用在后面加R的.后面也是同理.    }  else     {    r++,d--;    if (d<0) s+='R';    }  }cout<<s[2*n-1];//最后这个字母就是剩下的人.}

T4

题目

某国家的钱币都是3的自然数乘方,1,3,9,27……,有一天有人用同种钱币去购买一个商业机密,他带的钱足够多,但他没有零钱,恰好商店也没有钱找他,他想要付出尽可能少的钱能够买下这个商业机密,但是不能不够,输入商业机密的价格n,问他最少要支付几枚钱币?

思路

因为他没有零钱,所以他带的钱不能刚好买下商业机密.而且注意是尽可能少的钱,比如说输入价格为15,他不能用5个三元钱币买,因为刚好够,他也不能用一个27的钱币买,因为用两个9元的钱币比27要值.故这里应该输出2.
所以当n能被3,9整除时,付3元,9元之类的行不通,那就除以3,直到它不能被3整除.接下来的情况中你就相当于用3元钱币来购买.如果不用3元,用9元或者更大的钱币就会血亏.这里直接输出n/3+1即可.由于n很大,用long long.

#include<bits/stdc++.h>using namespace std;int main(){long long n;cin>>n;while (n%3==0) n/=3;cout<<n/3+1;}

T5

题目

有一种游戏,n*n的棋盘中,四个角是不能出现细胞的.你还要输入n个点,这n个点是禁止出现细胞的.你可以将很多细胞同时放在棋盘的上下左右,它们同时开始以同样的速度向着棋盘对面行进,如果它碰到了禁止的点,它就GG了.如果两个细胞相撞,就只剩下一个.一个细胞到达棋盘对面,你获得一分,求你最多能获得多少分.

思路

当两个细胞分别在行和列上,并且行号和列号相等,它们会相撞.可是让一个细胞从对面开始走回来就不会相撞.然而有一个坑点:对于n是奇数并且行和列的号码都是n/2+1,不论两个细胞从什么地方开始都一定会在中间相撞.这一块要分开讨论.
故代码如下.

#include<bits/stdc++.h>using namespace std;bool hang[1001],lie[1001];//定义行和列,对于每一个禁止输入的点,它所在的行和列是不能走的int main(){int n,m,i,s=0,x,y;cin>>n>>m;for (i=1;i<=m;i++)  {   scanf("%d%d",&x,&y);  hang[x]=1;  lie[y]=1;  } for (i=2;i*2<=n;++i) s+=4-(hang[i]+hang[n-i+1]+lie[i]+lie[n-i+1]);//从第二行和列开始讨论到n/2行和列,同时从第n-1行和列讨论到n/2+2行和列,只要这行或者这列不是不可走的就加1分if (n%2==1) if (hang[n/2+1]==0||lie[n/2+1]==0) s++;//单独讨论奇数方格中间行列 cout<<s; }
原创粉丝点击