• 计算机学院第五次ACM周赛题解


    目录

    HF的智能小车车

    Do you like Van game?

    好姐姐的三角形

    帮帮小陈

    卷点

    签个到就下班

    现在是摸鱼时间

    现在是摸鱼时间 PLUS


    HF的智能小车

    签到题目,

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. string arr;
    6. cin>>arr;
    7. if(arr=="R") cout<<"L";
    8. else if(arr=="L") cout<<"R"<
    9. else if(arr=="U") cout<<"D"<
    10. else if(arr=="D") cout<<"U"<
    11. }

    Do you like Van game?

    这道题目是个小模拟题目,模拟范围并不大,所以我们可以直接进行模拟。

    首先我们发现无非就是三种情况,最开始在1,2,3三个位置,我们可以直接开个变量假设就在初始的三个位置,然后对于每一次的交换,我们都把位置改变,接下来猜一下位置对不对,对了就把对应的答案加一;

    代码如下:

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. int n;
    6. cin>>n;
    7. int a=1,b=2,c=3;//假设abc为初始在123位置
    8. int ans1=0,ans2=0,ans3=0;// 记录猜对的次数
    9. while(n--)
    10. {
    11. int x,y,z;
    12. cin>>x>>y>>z;
    13. if(x==a) a=y;
    14. else if(y==a) a=x;
    15. if(x==b) b=y;
    16. else if(y==b) b=x;
    17. if(x==c) c=y;
    18. else if(y==c) c=x;
    19. //对于每一次交换,如果他交换了,就把他的位置改变
    20. if(a==z) ans1++;
    21. if(b==z) ans2++;
    22. if(c==z) ans3++;
    23. //三种初始位置分别计数
    24. }
    25. int ans=max(ans1,ans2);
    26. ans=max(ans,ans3);//求出最大猜对次数即可,不需要猜位置
    27. cout<
    28. }

    好姐姐的三角形

    也是很经典的一道模拟题目,输出经典的三角形,主要需要发现的是外面的空格个数和内层的空格个数,一定要思路清晰,不然空格个数判断错误的话很难改正。

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. int n;
    6. cin>>n;
    7. while(n--)
    8. {
    9. int a;
    10. char k;
    11. cin>>a>>k;
    12. int p=1;
    13. for(int i=a-1;i>=1;i--)//外层空格数目是逐渐减少,从a-1个开始减少
    14. {
    15. for(int j=1;j<=i;j++) cout<<" ";//这里是外层空格
    16. cout<
    17. if(i!=a-1)//注意,第一层中间没有空格
    18. {
    19. for(int j=1;j<=p;j++) cout<<" ";//如果中间需要空格,进行空格判断,增长规律是p+=2
    20. p+=2;
    21. cout<
    22. }
    23. cout<
    24. }
    25. for(int i=1;i<=2*a-1;i++) cout<//最后一层全是
    26. cout<
    27. cout<
    28. }
    29. }

    帮帮小陈

    目前不会写,先放着;

    三重循环别想,绝对超时,二分可以优化,但是没想到怎么做;

    卷点

    这道题目我们需要分类讨论,不难发现,有几个特殊点位需要我们注意

     当位于十字和斜线上的时候,我们会发现只有四种情况,可以通过对称实现,而当位于中心点四种情况会重叠,只有一种情况成立,其他情况我们发现都会有八种对称情况,那么根据分析,我们就可以把答案写出来了;

    1. #include
    2. #include
    3. using namespace std;
    4. typedef long long LL;
    5. int main()
    6. {
    7. int n;
    8. cin>>n;
    9. while(n--)
    10. {
    11. set se;//这里使用到的是c++STL中的set容器,具体放入set的元素不重复(自动去重)
    12. LL a,b,c,d;
    13. cin>>a>>b>>c>>d;
    14. se.insert(a);
    15. se.insert(b);
    16. se.insert(c);
    17. se.insert(d);//我们需要特判,这里的面积比其实是高之比
    18. if(a+b==c+d||a+c==b+d||a+d==b+c)//如果发现有两条边相加相等的情况,说明内部有卷点,如果有卷点,则绝对
    19. { //存在有两条边相加等于两条边相加,这样三角形高才能和正方形对应
    20. if(se.size()==4) cout<<"8"<//如果发现四条高各不相同,说明不在十字和X上
    21. else if(se.size()==2||se.size()==3) cout<<"4"<//2说明在X上,3说明是在十字上
    22. else if(se.size()==1) cout<<"1"<//四条高相等,只能在中点
    23. }
    24. else cout<<"0"<//否则高度相加不存在相等的情况肯定无解
    25. }
    26. }
    27. /*
    28. 补充set:S
    29. 小括号内定义你set可以放入什么类型的数据
    30. S.insert(A)函数表示把A加入容器。
    31. s.size()计算s的大小,元素不重复
    32. s.find(A)!=-1,在set里查找A,不到返回-1
    33. set的好处就是自动去重,保证每个元素只会出现一次
    34. */

    签个到就下班

    简单题目,签到题

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. char a,b;
    6. string arr;
    7. cin>>a>>b>>arr;
    8. int ans=0;
    9. for(int i=0;isize();i++)
    10. {
    11. if(arr[i]>=a&&arr[i]<=b) cout<' ';
    12. }
    13. }

    现在是摸鱼时间

    这道题目是一道很搞人的题目。

    我们先对式子进行化简,我们可以发现化简到最后得到j-i=arr[j]-arr[i];说明我们存入数组后,两个位置的下表之差等于他们数组存的数字的差;

    那么同学很快就想到了解决方案,我直接暴力循环,只要数组内两个数相减等于下标相减,答案就可以加一,事实上想法没错,但是数据范围在1e6。你是过不去的,会超时,那么我们再想一想,上式还可以化简:j-arr[j]=i-arr[i]也就是说,现在只需要保证下标和数组的差值相等,那么就可以记作一次答案相等;

    基于这个思想,我们就可以写出下面这个代码:

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. typedef long long LL;
    6. map<int,int> mp;//这里使用到了map
    7. int arr[1000010];
    8. int main()
    9. {
    10. int n;
    11. LL cnt=0;
    12. cin>>n;
    13. for(int i=1;i<=n;i++) cin>>arr[i],mp[i-arr[i]]++;//直接计算差值 ,把差值加入到map中
    14. for(auto &it:mp)//通过对map差值的遍历,如果出现5次就是10个相等,6个就是15个相等,规律是n个就是1+2+...+n-1
    15. {
    16. int k=it.second;
    17. for(int i=1;i//加入我们的答案
    18. }
    19. cout<
    20. //如果大家不会用map,可以再开一个数组,用这个数组记录差值,差值大小在-999-999之间,数组没负数下标
    21. //我们可以统一加一个1000,这样范围就在1-1999之间就可以存储,反正我们只要差值的出现次数,不管差值是
    22. //由谁减谁得到的
    23. }
    24. /*
    25. map类似字典,根据前一个东西可以定义后一个东西,后一个可以是int类型,也可以是string,甚至可以进行操作;
    26. 用法就是直接定义 A表示字典的第一个关键字,B是字典第二关键字,第二关键字可以进行操作;
    27. 具体详细用法请大家去csdn查看;
    28. */

    现在是摸鱼时间 PLUS

    这道题目实际是找两个互质的数字,他们的下标加起来最大是多少,记得不能是1,因为1不是质数不能参与互质运算。

    所以很多同学直接暴力,企图循环出1e6的答案,肯定错误,我们发现我们的数据大小在1-1000,但是下标在1-1e6,我们可以想个办法把下标对应到数据上,因为只要数据互质,下标我们只取最大的两个即可,所以我们首先对应下标;

    之后对数据进行互质判断,如果互质,直接相加即可,因为我们的第一步已经把下标最大存入这个数,所以直接相加一定是下标最大的相加,这样可以把原本1e6*1e6的算法变为1e3*1e3,可以过掉

    1. #include
    2. #include
    3. using namespace std;
    4. typedef long long LL;
    5. int arr[1010];
    6. int gcd(int a, int b)
    7. {
    8. return b>0 ? gcd(b, a % b) : a;
    9. }//判断互质函数,大家也可以写其他判断方法,这个是最简判断
    10. int main()
    11. {
    12. int n;
    13. LL cnt=0;
    14. cin>>n;
    15. for(int i=1;i<=n;i++)
    16. {
    17. int a;
    18. cin>>a;
    19. arr[a]=max(arr[a],i);//将下标对应到数据,且只要最大的
    20. }
    21. int ans=0;
    22. // for(int i=1;i<=10;i++) cout<
    23. for(int i=1;i<=1000;i++)
    24. {
    25. for(int j=i;j<=1000;j++)
    26. {
    27. if(i==j)//如果天数相同只算1次
    28. {
    29. ans=max(ans,arr[i]);
    30. if(i==1)//特判样例1 1,因为1 1不是指质数不能进行下面比较,但是1 1的确算作两次摸鱼,所以要特判
    31. ans=max(ans,arr[i]*2);
    32. }
    33. else if(gcd(i,j)==1&&i!=1&&j!=1)//如果互质,且没有1,就进行摸鱼答案判断
    34. {
    35. ans=max(ans,arr[i]+arr[j]);
    36. }
    37. }
    38. }
    39. cout<
    40. }

  • 相关阅读:
    FFmpeg源代码简单分析-其他-libswscale的sws_getContext()
    python批量删除excel文件中的sheet页
    NoSql的优势在哪里,NoSql是什么
    (八)MyBatis中参数的处理
    为什么资源隔离对HTAP至关重要?
    多图详解Windows恶意软件删除工具的常用操作
    uvm简介
    代码分析体系及Sonarqube平台
    RedisSearch深度解析:探索全文搜索的新境界
    Dubbo 知识点整理
  • 原文地址:https://blog.csdn.net/fakerzhang/article/details/127454943