• Codeforces Round #669 Div. 2


    第一次成功上分(?

    A. Ahahahahahahahaha

    这啥鬼名字(

    给定个由0,1组成的数列,从中删除不超过n/2的数,令新生成的数列奇数位和偶数位的和相等。
    我们知道一个数列要是全是0,或者全是1且长度是偶数,就满足条件了。
    所以,先遍历统计1的个数
    1.1的个数<=n/2,输出n/2个0就完事
    2.1的个数>n/2,输出n/2或者n/2+1个1,令数列长度为偶数

      #include <iostream>
      #include <algorithm>
      #include <cstdio>
      #include <cmath>
      #include <string>
      #include <cstring>
      #include<vector>
      #define lc(i) (2*i+1)
      using namespace std;
      typedef long long ll;
      int dataa[100000];
      int main() {
          ll ans = 0;
          ll n;
          cin >> n;
          while (n--)
          {
    	      ll k;
    	      cin >> k;
    	      ll sum1 = 0;
    	      for (int i = 0; i < k; i++) {
    		      scanf("%d", &dataa[i]);
    		      sum1 += dataa[i];
    	      }
    	      if (sum1 <= k / 2) {
    		      cout << k / 2 << '
    ';
    		      for (int i = 0; i < k/2; i++) {
    			      cout << "0 ";
    		      }
    	      }
    	      else {
    		      int cnt;
    		      if (k / 2 & 1)cnt = k / 2 + 1;
    		      else cnt = k / 2;
    		      cout << cnt << '
    ';
    		      for (int i = 0; i <cnt; i++)cout << "1 ";
    	      }
    	      cout << "
    ";
    
          }
      }
    

    B. Big Vova

    贪心就完事

      #include <iostream>
      #include <algorithm>
      #include <cstdio>
      #include <cmath>
      #include <string>
      #include <cstring>
      #include<vector>
      #define lc(i) (2*i+1)
      using namespace std;
      typedef long long ll;
      int dataa[100000];
      int gcd(int a, int b) {
          if (b == 0)return a;
          gcd(b, a % b);
      }
      int main() {
          ll ans = 0;
          ll n;
          cin >> n;
          while (n--)
          {
    	      ll k;
    	      cin >> k;
    	      ll sum1 = 0;
    	      for (int i = 0; i < k; i++) {
    		      scanf("%d", &dataa[i]);
    	      }
    	      sort(dataa, dataa + k);
    	      int ans = 0;
    	      for (int i = 0; i < k; i++) {
    		      int tmp1=0, ansm =-1;
    		      for (int j = 0; j < k; j++) {
    			      if (dataa[j] == -1)continue;
    			      if (gcd(dataa[j], ans) > ansm)tmp1 = j, ansm = gcd(dataa[j], ans);
    		      }
    		      cout << dataa[tmp1] << ' ';
    		      dataa[tmp1] = -1;
    		      ans = ansm;
    	      }
    	      cout << '
    ';
          }
      }
    

    C. Chocolate Bunny

    以前没写过交互。。。但是居然过了

    给定一个1到n的排列,每次可以询问第i个数模第j个数的值,在不超过2*n次询问获得这串排列
    我们知道a<b时a%b=a,b%a<a,因此可以询问a%b和b%a获得a的值。因此每2次询问,我们都能得到一个数,进行2*(n-1)次询问,最后遍历一遍确定最后一个数是多少即可。

      #include <iostream>
      #include <algorithm>
      #include <cstdio>
      #include <cmath>
      #include <string>
      #include <cstring>
      #include<vector>
      #define lc(i) (2*i+1)
      using namespace std;
      typedef long long ll;
      int dataa[100000];
      int gcd(int a, int b) {
          if (b == 0)return a;
          gcd(b, a % b);
      }
      int main() {
          ll ans = 0;
          ll n;
          cin >> n;
          memset(dataa, -1, sizeof(dataa));
          int l = 1, r = 1;
          for (int i = 1; i <n; i++) {
    	      int tmp1, tmp2;
    	      while (dataa[l] != -1)l++;
    	      r = l + 1;
    	      while (dataa[r] != -1)r++;
    	      cout << "? " << l << ' ' << r << '
    ';
    	      cout.flush();
    	      cin >> tmp1;
    	      cout << "? " << r << ' ' << l << '
    ';
    	      cout.flush();
    	      cin >> tmp2;
    	      if (tmp1 > tmp2)dataa[l] = tmp1;
    	      else dataa[r] = tmp2;
          }
          int pos = 0;
          for (int i = 1; i <= n; i++) {
    	      ans += dataa[i]; if (dataa[i] == -1) {
    		      pos = i;
    		      ans++;
          	      }
          }
          dataa[pos] = n*(n+1)/2-ans;
          cout << "! ";
          for (int i = 1; i <= n; i++) {
    	      cout << dataa[i] << ' ';
          }
          cout << endl;
          cout.flush();
    
      }
    

    D. Discrete Centrifugal Jumps

    单调栈/DP
    不会(

    给定一个h数组,按以下规则(i<j)进行移动,问从h[1]到h[n]最少要多少步

    • j=i+1
    • max(hi+1,…,hj−1)<min(hi,hj)
    • max(hi,hj)<min(hi+1,…,hj−1)
      首先考虑DP,状态dp[i]为从第一个点到第i个点需要的最小步数
      然后考虑单调栈优化,单调栈可以用于求以某个数为最值的最大区间 参考单调栈&单调队列
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include<vector>
    #include<iomanip>
    #include<map>
    #include<queue>
    #include<stack>
    #define lc(i) (2*i+1)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    int n, k;
    stack<long long>up,down;
    ll dataa[1000000 + 5];
    ll dp[1000000 + 5];
    int main() {
    	cin >> n;
    	for (int i = 0; i < n; i++)scanf("%d",&dataa[i]);
    	memset(dp, 0x3f, sizeof(dp));
    	dp[0] = 0;
    	up.push(0);
    	down.push(0);
    	for (int i = 1; i < n; i++) {
    		dp[i] = dp[i - 1] + 1;
    		while (!up.empty() && dataa[up.top()] <= dataa[i])
    		{
    			ll x = dataa[up.top()];
    			up.pop();
    			if(!up.empty()&&x<dataa[i])
    			dp[i] = min(int(dp[i]), int(dp[up.top()] + 1));
    		}
    		up.push(i);
    		while (!down.empty()&&dataa[down.top()]>=dataa[i])
    		{
    			ll x = dataa[down.top()];
    			down.pop();
    			if (!down.empty() && x > dataa[i])
    			dp[i] = min(int(dp[i]), int(dp[down.top()] + 1));
    		}
    			down.push(i);
    	}
    	cout << dp[n - 1];
    }
    
    K-ON!!
  • 相关阅读:
    js实现input button从不可用变为可用
    eclipse工程名出现小红叉的解决办法
    jQuery的dataTables插件实现中文排序
    禁用鼠标选中DOM
    获取当前JS所在文件夹
    解决方案:在移动端输入框在软键盘弹出后位置矫正
    MUI版本升级更新程序IOS和andriod
    JavaScript输入表单数据正则验证规则
    Windows安裝PHP環境
    CentOS下安装PHP
  • 原文地址:https://www.cnblogs.com/pophirasawa/p/13642041.html
Copyright © 2020-2023  润新知