首页 > 其他分享 >11.8 总结

11.8 总结

时间:2022-11-08 18:58:25浏览次数:73  
标签:总结 11.8 int tv ans frac now SIZE

11.8 GZEZ NOIP2022模拟测试赛(五十六)

T1 环:

题目描述:对于一个0,1串有两种操作 :

    1. 整体向右移动x位
    1. 将某个01变成10

给你串的长度和1的个数让你构造l个串 , 满足s[i]可以即经过第一种也可以经过第二种
操作变s[i+1]

Solution

我们先考虑是否有解:
若n,k互质则有解 , 证明:
设\(W_i\)为串中1的下标和
经过第一种操作\(W_{i+1}= W_i + x*k (mod n )\)
经过第二种操作\(W_{i+1}=W_i+1(mod n)\)
所以若有解则\(x * k \equiv 1\) 德x , k 互质
因为kn互质,所以k一定存在 \(\bmod n\)意义下的逆元,令s[0]的 \(\frac{0}{k}\),\(\frac{1}{k}, \cdots, \frac{k-1}{k}\) 位置处为1 , 其余处为0, 同样的对于\(s[i]\),我们令其\(\frac{i}{k}, \frac{i+1}{k}, \cdots, \frac{k+i-1}{k}\)处为1,其余处为0。显然,从\(s[i]\)变成\(s[i+1]\)可以通过向右循环移位\(\frac{1}{k}\)实现,同 时发现\(\frac{i}{k}+1=\frac{k+(i+1)-1}{k}\),于是我们将\(s[i]\)的\(\frac{i}{k}\)位置变成 0,将 \(\frac{i}{k}+1\)位置变成1即可用b操作将\(s[i]\)变成\(s[i+1]\)。

Code:

#include<bits/stdc++.h>
using namespace std ;
const int SIZE = 105 ;

char s[SIZE] ;

int n , k , l ;

int exgcd(int a , int b , int &x , int &y){
   if(!b){
      x = 1 ;
      y = 0 ;
      return a ;
   }
   int d = exgcd(b , a % b , y , x) ;
   y -= (a / b * x) ;
   return d ;
}

inline int inv(int a , int b){
   int x , y ;
   exgcd(a , b , x , y) ;
   return (x % b + b) % b ;
}

int main(){
   int T ; cin >> T ;
   while(T-->0){
      cin >> n >> k >> l ;
      if(__gcd(n , k) != 1){
         cout << "NO" << endl ;
         continue ;
      }  
      else cout << "YES" << endl ;
      int iv = inv(k , n) ;
      
      for(int i = 1 ; i <= l ; i += 1){
         memset(s , '0' , sizeof s) ;
         for(int j = 0 ; j < k ; j += 1){
            s[(i + j) * iv % n] = '1' ;
         }
         
         s[n] = '\0';
         cout << s << endl ;
      }
   }
}

T2:DNA序列

题目描述:

给你n个字符串其中只包含"A , T , C , G" ,我们要取每个字符串的一个非空前缀然后随意> 拼接使得字典序最小

Solution:

正解:https://yhx-12243.github.io/OI-transit/records/uoj494.html

乱搞:随机化shuttfle\

Code

Code:
#include<bits/stdc++.h>
using namespace std;
const int N = 55;
int n;bool pre[N];
string s[N],t[N];
string solve(int x)
{
    if(x==n) return s[x].substr(1,1);
    string ans = solve(x+1);
    vector<string>tmp;
    for(int i=1;i<s[x].size();i++)
    {
        tmp.emplace_back(s[x].substr(1,i)+ans);
    }
    sort(tmp.begin(),tmp.end());
    return tmp[0];
     
}
mt19937 rd(time(0));
mt19937 rdd(time(0));
int main()
{
    cin >> n; int i;
    for(i=1;i<=n;i++) cin >> s[i],s[i] =" " + s[i];
    string ans = solve(1);int T = 4200;
    sort(s+1,s+n+1);
    ans = min(ans,solve(1));
    while(T-->0){
    	int l = rd()%n+1;
    	int r = rd()%n+1;
    	swap(s[l],s[r]);
    	string  now = solve(1);
    	if(now > ans) swap(s[l],s[r]);
        else ans = now;
    }
    cout << ans << '\n';
    return 0;
}

T3探寻

题面描述:

给你一张图,每个点都有一个权值表示当到达这个点时所获得的收益,每条边有一个边权表示要经>过这条边的花费(花费和收益只能用一次),起点是0,问到达目标点的最小起始花费

Solution:

map上跑启发式合并
先按既定条件排序:
价值 = 收益 - 代价

  • 1.价值为正 , 价值大的比价值小的优先级靠前
  • 2.价值为负 ,代价小的优先
  • 3.价值为负,代价相同,收益大的有限

Code:

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int SIZE = 2e5 + 20 ;
const ll inf = 1e18 ;
#define pa pair<ll,ll> 
#define fi first 
#define se second
#define ma(x,y) make_pair(x,y)

ll w[SIZE] , v[SIZE] ;
int n ;
multiset<pa> s[SIZE] ;
vector<int> g[SIZE] ;

void dfs(int now){
    for(auto v : g[now]){
        dfs(v) ;
        if(s[now].size() < s[v].size()) swap(s[now] , s[v]) ;
        s[now].insert(s[v].begin() , s[v].end()) ;
        s[v].clear() ;
    }
    
    ll tw = w[now] ;
    ll tv = v[now] - w[now] ;
    
    while(!s[now].empty() && (tv <= 0 || tw >= s[now].begin()->first)){
        auto tmp = *s[now].begin() ;
        tw += max(0ll , tmp.first-(tw+tv)) ;
        tv += tmp.se ;
        s[now].erase(s[now].begin()) ;
    }
    if(tv > 0) s[now].insert(ma(tw,tv)) ;
    else s[now].clear() ;
}

int main(){
    cin >> n ;
    w[1] = inf ;
    for(int i = 2 ; i <= n ; i += 1){
        int x ; cin >> x ;
        cin >> v[i] >> w[i] ;
        g[x+1].emplace_back(i) ;
        if(v[i] == -1) v[i] = inf * 2 ;
    }
    dfs(1) ;
    cout << s[1].begin() -> first - inf ;
}

标签:总结,11.8,int,tv,ans,frac,now,SIZE
From: https://www.cnblogs.com/guier/p/16870794.html

相关文章

  • oracle case when 用法总结
    ​​Oracledbms_jobpackage用法小结​​ORACLECASEWHEN及SELECTCASEWHEN的用法  Case具有两种格式。简单Case函数和Case搜索函数。--简单case函数casesex......
  • Spring Boot面试题总结
    1、什么是SpringBoot描述:SpringBoot是Spring社区发布的一个开源项目,旨在帮助开发者快速并且更简单的构建项目。大多数SpringBoot项目只需要很少的配置文件。2、Spring......
  • LPDDR4x 的 学习总结(6) - initialization & training
    1.为什么要initialization?本节介绍device的initialization从上节的device的结构可看出DIMM的两面有16个颗粒,颗粒的组织结构有T型(CA/CLK)。 T型拓扑T型拓扑的眼图......
  • android 经典笔记总结
    pro android media developing graphics,music,videoand richmedia apps for smartphones and tablets第一章 android introduction  pla......
  • Graphics Stack总结(四) 设置Mesa开发环境
    回顾上篇文章中我们提供了Mesasourcetree的概览,然后简介了几个主要的modules.现在我们将介绍setupmesa开发环境时会用到的几个小tips。DevelopmentenvironmentMesa......
  • 【日总结】2022.11.8
    连续AK十年IOI的熊子豪大帅哥出的模拟赛果然恐怖如斯。)今天下午没时间了,可能只有一道题。2022NOIPA层联测23T2口粮运输应当减少口胡时候看题解的频率。部分分......
  • opencv筛选轮廓的几种方法总结
    在使用opencv处理图像的时候,在获取ROI区域这一步用的最多的就是找到指定区域,一般是根据轮廓提取,我们可以通过opencv中的findContours()函数来查找图片中的轮廓,但是会发现找......
  • app日常优化总结
    滑动冲突有时候viewpager嵌套webview后,左右滑动冲突,直接消费或者处理拦截导致上下不能滑动,所以需要根据滑动情况判断处理,只在上下滑动时判断事件交给子viewclassScroll......
  • 【Python零基础入门篇 · 36】:greenlet协程模块的使用、gevent模块的使用、程序打补丁
    greenlet协程模块的使用greenlet:是一个用C实现的协程模块,通过switch()来实现任务函数间的切换。greenlet属于手动切换任务,当遇到IO操作,程序会阻塞,而不能进行自动切换。g......
  • 【Python零基础入门篇 · 36】:greenlet协程模块的使用、gevent模块的使用、程序打补丁
    greenlet协程模块的使用greenlet:是一个用C实现的协程模块,通过switch()来实现任务函数间的切换。greenlet属于手动切换任务,当遇到IO操作,程序会阻塞,而不能进行自动切换。g......