Goodbye 2019

QAQ:这场比赛在凌晨,于是乎没打。开了重现,A掉三题,这大概就是我现在的水平了吧

A. Card Game

简单题,看谁的牌最大

#include<bits/stdc++.h>
using namespace std;
int a[105],b[105];
int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        int n,k1,k2;
        cin >> n >> k1 >> k2;
        for(int i = 0;i<k1;i++)
        {
            cin >> a[i];
        }
        for(int i =0;i<k2;++i)
            cin >> b[i];
        bool flag = false;
        for(int i = 0;i<k1;++i)
        {
            if(a[i]==n)
            {
                flag = true;
                break;
            }
        }
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

 

B. Interesting Subarray

简单题,思路就是比较相邻的两个数,如果之差>1,则代表这是符合题意的解,如果没有,则证明整个数组不存在解。

 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int num[maxn];
int main()
{
   int T;
   cin >> T;
   while(T--)
   {
       int n;
       cin >> n;
       for(int i = 0;i<n;i++)
       {
           cin >>num[i];
       }
       bool flag = false;
       int l = 0,r = 0;
       for(int i =0;i<n-1;i++)
       {
           if(abs(num[i]-num[i+1])>1)
           {
               flag =true;
               l = i,r = i+1;
               break;
           }
       }
       if(!flag)
            printf("NO\n");
       else
       {
           printf("YES\n");
           printf("%d %d\n",l+1,r+1);
       }
 
 
   }
    return 0;
}

 

 

 

C. Make Good

简单题,我们可以先把等式左边算出来,记为a,右边算出来,记为b,根据异或的性质,先向数组中添加一个数b,左边变成a+b,右边变成0,再加入数a+b,即可符合题意,这两个数也就是所求。

 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
LL num[maxn];
int main()
{
  int T;
  cin >>T;
  while(T--)
  {
      int n;
      cin >> n;
      for(int i = 0;i<n;++i)
      {
          cin >> num[i];
      }
      LL ans = num[0],ans2 = num[0];
      for(int i = 1;i<n;i++)
      {
          ans+=num[i];
          ans2^=num[i];
      }
      if(ans == ans2*2)
      {
          printf("0\n\n");
      }
      else
      {
          cout << 2 << endl;
          cout << ans2 << " " << ans+ans2 << endl;
      }
  }
    return 0;
}

 

 

 

Ps:  以下题解均来自cf的官方题解

D. Strange Device

交互题,这也是我第一次做交互题,很懵,题没读懂。

题意:给你一个有n个元素的数组a,并保证其中的元素两两不同,你有一个机器,这个机器接受输入k个输入的位置,返回在这k个位的数经过排序以后的m-th的数在a里的位置和他的值。让你通过不超过n次的询问,计算出m的大小。

思路:

稳定查询k+1次,每次用第k+1的数替换1-k+1的一个数,设1-k+1中的第m-th大的数为 a,第m+1-thb,则由题意可知,b会出现m次,a则会出现k+1-m次,因此,记录每次查询返回的值,其中最大的是b,记录一下b的出现次数,即可以计算出m

 

#include <bits/stdc++.h>
 
using namespace std;
 
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr);
 
    int n, k;
    cin>>n>>k;
    vector<int> elements;
    for (int i = 1; i<=k+1; i++)
    {
        cout<<"? ";
       
        for (int j = 1; j<=k+1; j++) if (j!=i) cout<<j<<' ';
        cout<<endl;
       
        int pos, el;
        cin>>pos>>el;
        elements.push_back(el);
    }
    int maxx = elements[0];
    for (auto it: elements) maxx = max(maxx, it);
    int m = 0;
    for (auto it: elements) if (it==maxx) m++;
    cout<<"! "<<m<<endl;
 
}

 

 

 

E. Divide Points

题意:将给定点集分为两部分,设属于同一部分的任意两点的距离为集合A,属于不同部分任意两点的距离为集合B,请输出其中一个满足题意的集合。

思路:我们可以根据奇偶性把点分为A00,A01,A10A11 这四类,先考虑第一种分类假如A00 +A11>0&&A01 +A10>0我们可以证明 集合A中的数全是偶数,集合B中的数全是奇数,假如第一类分类不行,则证明剩下的全是A00A11 或者全是,A01,A10 则可进行第二种分类,假如是第一种情况 则可以证明集合A中全是可以整除4,集合B中全是除42的数,如果是第二种情况,也可以证明集合A中全是可以整除4,集合B中全是除42的数。如果第二种分类也不成立,则证明当前条件下仅存在上述四种情况下的一种,所以我们可以找出他们属于哪一类点,并且针对于这个对点进行坐标变换,重复上述操作,直到找到解。

 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3+10;
struct Node
{
    int x,y;
    Node(int _x = 0,int _y = 0):x(_x),y(_y) {}
};
Node Point[maxn];
int cnt[3][3]  = {0};
int main()
{
    int n;
    scanf("%d",&n);
    for(int i = 0; i<n; i++)
    {
        scanf("%d %d",&Point[i].x,&Point[i].y);
        Point[i].x+=int(1e6);
        Point[i].y+=int(1e6);
    }
    while(true)
    {
        memset(cnt,0,sizeof(cnt));
        for(int i = 0; i<n; ++i)
        {
            int x = Point[i].x,y = Point[i].y;
            ++cnt[x%2][y%2];
        }
        if(cnt[0][0]+cnt[1][1]>0&&cnt[0][1]+cnt[1][0]>0)
        {
            printf("%d\n",cnt[0][0]+cnt[1][1]);
            int cur = 0;
            for(int i = 0; i<n; i++)
            {
                int x = Point[i].x,y = Point[i].y;
                if((x%2==0&&y%2==0)||(x%2==1&&y%2==1))
                {
                    if(cur==0)
                        printf("%d",i+1);
                    else
                        printf(" %d",i+1);
                    ++cur;
                }
            }
            return 0;
        }
        if(cnt[0][0]+cnt[1][0]>0&&cnt[1][1]+cnt[0][1]>0)
        {
            printf("%d\n",cnt[0][0]+cnt[1][0]);
            int cur = 0;
            for(int i = 0; i<n; i++)
            {
                int x = Point[i].x,y = Point[i].y;
                if((x%2==0&&y%2==0)||(x%2==1&&y%2==0))
                {
                    if(cur==0)
                        printf("%d",i+1);
                    else
                        printf(" %d",i+1);
                    ++cur;
                }
            }
            return 0;
        }
        int x = 0;
        int y = 0;
        for(int i = 0; i<2; ++i)
        {
            for(int j = 0; j<2; ++j)
            {
                if(cnt[i][j])
                {
                    x = i;
                    y = j;
                    break;
                }
            }
        }
        for(int i = 0; i<n; i++)
        {
            Point[i].x = (Point[i].x-x)/2;
            Point[i].y = (Point[i].y-y)/2;
        }
        // return p;
    }
 
 
    return 0;
}

 

 

 

G.Subset with Zero Sum

将表达式变化可以得到 1<= i-ai<=n,因此我们可以将其转化为一个有向图,对于每一个点i,都连接一条边到点(i-ai),我们最后能在这个图上找到一个有向环。这条环上的所有点之和必定为0,可以列出等式来证明。

 

#include <bits/stdc++.h>
using namespace std;
void solve()
{
    int n;
    cin >> n;
    vector<int> a(n+1);
    for(int i = 1;i<=n;++i)
        cin >> a[i];
    vector<bool> visited(n+1);
    int cur = 1;
    while(!visited[cur])
    {
        visited[cur] = true;
        cur = cur -a[cur];
    }
    vector<int> ans = {cur};
    int cur1 = cur - a[cur];
    while(cur1!=cur)
    {
        ans.push_back(cur1);
        cur1 = cur1-a[cur1];
    }
    cout << ans.size() << '\n';
    for(auto it:ans) cout << it << " ";
    cout << '\n';
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr);
    int t;
    cin >> t;
    for(int i = 0;i<t;i++)
        solve();
    return 0;
}
posted @ 2020-01-08 16:57  浅花迷人  阅读(...)  评论(...编辑  收藏