2020牛客多校训练第三场 部分

L 、 Problem L is the Only Lovely Problem
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define x first
#define y second
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
ll in()
{
  ll x = 0 , f = 1 ;
  char ch = getchar() ;
  while(!isdigit(ch)) {if(ch == '-') f = -1 ; ch = getchar() ;}
  while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
  return x * f ;
}
int main()
{
  string s ;
  cin >> s ;
  string a = "lovely" ;
  for(int i = 0 ;i < 6 ;i ++ ) {
    if(i >= s.size()) break ;
    if(s[i] < 'a') s[i] += 32 ;
    if(s[i] != a[i]) return 0 * puts("ugly") ;
   }
  return 0 * puts("lovely") ;
}
/*
*/

B、Classical String Problem
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define x first
#define y second
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 2e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
ll in()
{
  ll x = 0 , f = 1 ;
  char ch = getchar() ;
  while(!isdigit(ch)) {if(ch == '-') f = -1 ; ch = getchar() ;}
  while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
  return x * f ;
}
char s[N] ;
int main()
{
  scanf("%s" , s) ;
  int n = in() ;
  int len = strlen(s) ;
  int l = 0 , r = len - 1 ;
  for(int i = 1; i <= n ;i ++ ) {
    char c[2] ;
    int x ;
    scanf("%s%d" , c , &x) ;
    if(c[0] == 'A') printf("%c\n" , s[((l + x - 1) % len + len) % len]) ;
    else l += x , r += x , (l %= len + len) %= len , (r %= len + len) %= len ;
  }
  return 0 ;
}
/*
*/

A、Clam and Fish
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define x first
#define y second
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 2e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
char s[N] ;
void work(){
  int n ;
  scanf("%d" , &n) ;
  int ans = 0 , res = 0 ;
  scanf("%s" , s) ;
  for(int i = 0 ;i < n ;i ++) {
    if(s[i] >= '2') {
      ans ++ ;
    }
    if(s[i] == '0') {
        if(res) res -- , ans ++ ;
    }
    if(s[i] == '1') 
        res ++ ;
  }
  printf("%d\n" , ans +  res / 2) ;
  return ;
}
int main()
{
  int t ;
  scanf("%d" , &t) ;
  while(t --) work() ;
  return 0 ;
}
/*
*/

c、Operation Love
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define x first
#define y second
typedef long long ll ;
const double esp = 1e-5 , pi = acos(-1) ;
typedef pair<double , double> PII ;
const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
ll in()
{
  ll x = 0 , f = 1 ;
  char ch = getchar() ;
  while(!isdigit(ch)) {if(ch == '-') f = -1 ; ch = getchar() ;}
  while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
  return x * f ;
}
PII a[N] ;
int len(PII a , PII b){
  double x = a.x - b.x , y = a.y - b.y ;
  return sqrt(x * x + y * y + 0.5) ;
}
double cross(PII a , PII b){
  return a.x * b.y - a.y * b.x ;
}
double area() {
  double ans = 0 ;
  for(int i = 0 ;i < 20 ;i ++)
    ans += cross(a[i] , a[(i + 1) % 20]) ;
  return ans ;
}
void work()
{
  vector<int> ans ;
  for(int i = 0; i < 20 ;i ++ ) cin >> a[i].x >> a[i].y ;
  if(area() > 0) {
    for(int i = 0; i < 20 ;i ++) {
      if(len(a[i] , a[(i + 1) % 20]) == 9) {
        if(len(a[(i + 1) % 20] , a[(i + 2) % 20]) == 8) cout << "right" << endl ;
        else cout << "left" << endl ;
        return ;
      }
    }
  }else {

    for(int i = 0; i < 20 ;i ++) {
      if(len(a[i] , a[(i + 1) % 20]) == 9) {
        if(len(a[(i + 1) % 20] , a[(i + 2) % 20]) == 8) cout << "left" << endl ;
        else cout << "right" << endl ;
        return ;
      }
    }
  }
  return ;
}
int main()
{
  int n = in() ;
  while(n --) work() ;
  return 0 ;
}
/*
*/

E、Two Matchings

首先
p p [ i ] = i , 那 么 p i = p [ i ] 例 如 p 5 = 3 , 那 么 就 是 i = 3 , p 3 = 5 p_{p[i]} = i, 那么p_i = p[i]\\例如p_5 = 3,那么就是i = 3, p_3 = 5 pp[i]=i,pi=p[i]p5=3,i=3,p3=5
根据上述,发现一个目标n的排列里面,都是一个一个的环,并且每个环的长度为2 , 题目要求两个那个matching串和最小,就贪心使每个串的和比较小,也就是找个最小和次小,那么第一个matching最小的话,肯定是直接将a排序,a[1] < a[2] < a[3] < a[4] , 这个贡献就是a[i + 1] - a[i] , i += 2, 那么次小的怎么算呢
a [ 1 ] < a [ 2 ] < a [ 3 ] < a [ 4 ] < a [ 5 ] < a [ 6 ] < a [ 7 ] < a [ 8 ] a[1] < a[2] < a[3] < a[4] < a[5] < a[6] < a[7] < a[8] a[1]<a[2]<a[3]<a[4]<a[5]<a[6]<a[7]<a[8]
最 小 的 安 排 是 a [ 2 ] − a [ 1 ] , a [ 4 ] − a [ 3 ] , a [ 6 ] − a [ 5 ] 最小的安排是a[2] - a[1] , a[4] - a[3] , a[6] - a[5] a[2]a[1],a[4]a[3],a[6]a[5]
在这里插入图片描述

贪心讲:次小的应该是错开一个减,例如a[3] - a[1] , a[4] - a[2],但是枚举6个时候应该是a[6] - a[4] ,. a[5] - a[2] , a[3] - a[1], 如下图, 那么8个时候怎么错开,发现就是两个4错开,10个时候错开的话就是一个4和一个6组合,下面也就是dp了,每次dp就max一下上面两种错开方式的最大值
在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define x first
#define y second
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
ll in()
{
  ll x = 0 , f = 1 ;
  char ch = getchar() ;
  while(!isdigit(ch)) {if(ch == '-') f = -1 ; ch = getchar() ;}
  while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
  return x * f ;
}
ll a[N] , dp[N] ;
void work(){
  int n = in() ;
  for(int i = 1; i <= n ;i ++ ) a[i] = in() , dp[i] = 1e18 ;
  sort(a + 1 , a + n + 1) ;
  ll ans = 0 ;
  for(int i = 1; i <= n ;i += 2) {
    ans += a[i + 1] - a[i] ;
  }
  dp[0] = 0 ;
  for(int i = 4; i <= n ;i ++ ) {
    dp[i] = min(dp[i] , dp[i - 4] + a[i] - a[i - 2] + a[i - 1] - a[i - 3]) ;
    if(i >= 6)
     dp[i] = min(dp[i] , dp[i - 6] + a[i] - a[i - 2] + a[i - 1] - a[i - 4] + a[i - 3] - a[i - 5]) ;
  }
  printf("%lld\n" , dp[n] + ans) ;
  return ;
}
int main()
{
  int n = in() ;
  while(n --) work() ;
  return 0 ;
}
/*
*/

F、 Fraction Construction Problem
  1. 玄学卡常可能,ll不能多用

  2. 我看的别的博客说b如果是质数的话,输出-1,但是这个地方好象不行,质数好象是可以的,如果a == b是可以的,不管b是否指数

  3. 如果gcd(a , b) > 1 , 直接构造 a g c d ( a , b ) + 1 b g c d ( ) a , b − 1 b g c d ( a , b ) \frac{\frac{a}{gcd(a , b)} + 1}{\frac{b}{gcd()a , b}} - \frac{1}{\frac{b }{gcd(a , b)}} gcd()a,bbgcd(a,b)a+1gcd(a,b)b1

  4. 如果gcd(a , b) == 1 , 通分 c d − d e d f = a b \frac{cd - de}{df} = \frac{a}{b} dfcdde=ba构造的话,就 d ∗ f = b & & g c d ( d , f ) = 1 d*f = b\&\&gcd(d , f) = 1 df=b&&gcd(d,f)=1
    为啥要加上gcd(d , f) = 1呢
    假设不等于1的情况: t = g c d ( d , f ) t = gcd(d , f) t=gcd(d,f) , d , f也是b的约数,那么t也就是b的因子。在对 c d − d e cd - de cdde扩展欧几里得的过程里面, c f − d e = g c d ( d , f ) cf - de = gcd(d , f) cfde=gcd(d,f) , 并且最终呢我们要 c f − d e = a cf - de = a cfde=a , 也就是说 g c d ( d , f ) gcd(d , f) gcd(d,f) 是a的因子,那么 g c d ( d , f ) gcd(d , f) gcd(d,f)也是b的因子,所以此时 g c d ( a , b ) > 1 gcd(a , b) > 1 gcd(a,b)>1 , 与假设 g c d ( a , b ) = = 1 gcd(a , b) == 1 gcd(a,b)==1, 不符合
    5.枚举d,得到f, g c d ( d , f ) = = 1 gcd(d , f) == 1 gcd(d,f)==1, 然后就直接扩展欧几里得求解c , e,判断c , e的正负即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define x first
#define y second
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 3e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
ll in()
{
  ll x = 0 , f = 1 ;
  char ch = getchar() ;
  while(!isdigit(ch)) {if(ch == '-') f = -1 ; ch = getchar() ;}
  while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
  return x * f ;
}
ll exgcd(ll a , ll b , ll &x , ll &y){
  if(b == 0) {
    x = 1 , y = 0 ;
    return a ;
  }
  ll t = exgcd(b , a % b , y , x) ;
  y -= 1ll * (a / b) * x ;
  return t ;
}
int work(){
  int a , b ;
  scanf("%d%d" , &a , &b) ;
  if(b == 1) {
    return 0 * puts("-1 -1 -1 -1") ;
  }
  int g = __gcd(a , b) ;
  if(g != 1) {
    printf("%d %d %d %d\n" ,  a / g + 1 ,  b / g , 1 , b / g ) ;
    return 0 ;
  }
  for(int i = 2; i * i <= b ;i ++ ) {
    if(b % i == 0 && __gcd(i , b / i) == 1) {
      ll e , c ;
      exgcd(i ,  b / i , e  , c ) ;
      e *= a , c *= a ;
      if(c < 0 && e > 0) {
         printf("%lld %d %lld %d\n" , e ,b / i , -c , i ) ;
        return 0 ;
      }else  {
        printf("%lld %d %lld %d\n" , c , i , -e , b / i  )  ;
          return 0 ;
      }
      break ;
    }
  }
  return 0 * puts("-1 -1 -1 -1") ;
}
int main()
{
  int n ;
  scanf("%d" , &n) ;
  while(n --) work() ;
  return 0 ;
}
/*
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值