奋斗群群赛7总结与心得

总体情况

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; 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值