ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

牛客寒假6

2022-02-21 21:02:44  阅读:175  来源: 互联网

标签:std int ++ 牛客 寒假 ans -- mod


 1、进制模拟

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int k;
    std::cin >> k;
    
    std::string s, t;
    std::cin >> s >> t;
    
    std::reverse(s.begin(), s.end());
    std::reverse(t.begin(), t.end());
    
    int n = std::max(s.length(), t.length());
    
    std::vector<int> a(n);
    for (int i = 0; i < int(s.length()); i++) {
        a[i] += s[i] - '0';
    }
    for (int i = 0; i < int(t.length()); i++) {
        a[i] += t[i] - '0';
    }
    
    for (int i = 0; i < n; i++) {
        if (a[i] >= k) {
            if (i == n - 1) {
                a.push_back(0);
                n++;
            }
            a[i + 1]++;
            a[i] -= k;
        }
    }
    
    for (int i = n - 1; i >= 0; i--) {
        std::cout << a[i];
    }
    std::cout << "\n";
    
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
//C = A + B
int k;
vector<int> add(vector<int> &A, vector<int> &B)
{
  vector<int>C;
  int t = 0;//进位
  for(int i = 0; i < A.size() || i < B.size(); i++)
  {
      if(i < A.size()) t += A[i];
      if(i < B.size()) t += B[i];
      C.push_back(t % k);
      t /= k;
  }   
  if(t) C.push_back(1);
  return C;
}
int main()
{
    string a, b;
    scanf("%d",&k);
    vector<int> A, B;
    cin >> a >> b;//a = "123456"
    for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');//A =[6,5,4,3,2,1];
    for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
    auto C = add(A, B);
    //vector<int>C = add(A,B);
    for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
    system("pause");
    return 0;
}
int k, la, lb;
char a[200005], b[200005], c[200005];
int main() {
    cin >> k >> a >> b;
    reverse(a, a + strlen(a));
    reverse(b, b + strlen(b));
    for (int i = 0; a[i] || b[i] || c[i]; i++) {
        if (a[i]) c[i] += a[i] - '0';
        if (b[i]) c[i] += b[i] - '0';
        if (c[i] >= k) c[i] -= k, c[i + 1] += 1;
        c[i] += '0';
    }
    reverse(c, c + strlen(c));
    cout << c << endl;
    return 0;
}

2、+-串模拟 or 规律

纸上写几个例子 注意到 由+ --> - x-=2,由 - ---> + x+=2

真正的模拟

while (T--) {
        scanf("%s", s + 1);
        read(k);
        int n = strlen(s + 1);
        int a = 0, b = 0;
        rep(i, 1, n) {
            if (s[i] == '+')
                ++a;
            else
                ++b;
        }

        这个地方运用了模拟的思想!! 不用推式子!! 直接模拟
        while (k && abs(a - b) > 1) {
            if (a > b)
                --a, ++b;
            else
                ++a, --b;
            --k;
        }


        if(abs(a - b) == 1){cout << "1" <<endl;return 0;}
        if (k) {
            if (k % 2)
                print(2, '\n');
            else
                print(0, '\n');
        } else {
            print(abs(a - b), '\n');
        }
    }
    int balance = 0;
    for (auto c : s) {
        if (c == '+') {
            balance++;
        } else {
            balance--;
        }
    }
     
    balance = std::abs(balance);
     
    int t = std::min(balance / 2, k);
    这一步妙。自行体会。

    balance -= 2 * t;
     (除了特判都符合这个)

    if ((k - t) % 2 == 1 && balance == 0) {
        balance = 2;
    }(特判)
     
    std::cout << balance << "\n";
}

 E、骑士

维护第二大的值max2的时候 首先如果max1被更改,max2一定会改;
然后如果a【i】> mx2 也可以更改mx2 
即mx2的更改有两条途径 
if(a[i]>=mx1){
                mx2=mx1;
                mx1=a[i];id1=i;
            }
            else if(a[i]>=mx2){
                mx2=a[i];
            }

 前缀后缀max

  • 下面这个程序for循环再多只要是并列就是On,下面这个程序是On的
  • 前缀后缀用空间换时间O1查询
pre控制i左边的max1,suf控制i右边的max2
void work() {
    scan(n);
    for(int i = 1; i <= n; ++i) scan(a[i]), scan(b[i]), scan(h[i]);
    pre[0] = 0; for(int i = 1; i <= n; ++i) pre[i] = max(pre[i - 1], a[i]);
    suf[n + 1] = 0; for(int i = n; i >= 1; --i) suf[i] = max(suf[i + 1], a[i]);
    ll ans = 0;
    for(int i = 1; i <= n; ++i) {
        int mx = max(pre[i - 1], suf[i + 1]);   //除了i之外的最大项    
        if(mx >= b[i] + h[i]) ans += mx - b[i] - h[i] + 1;
    }
    print(ans, '\n');
}

D、删除子序列

有点像dp  形成abc的前提是有ab ab的前提是有a a没有前提为inf

int n, m;
char s[M + 5], t[M + 5];
int cnt[30];
 
void work() {
    scan(n), scan(m);
    scanf("%s", s + 1), scanf("%s", t + 1);
    memset(cnt, 0, sizeof cnt);
    cnt[0] = inf;
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= m; ++j) {
            if(s[i] == t[j]) {
                if(cnt[j - 1]) {
                    --cnt[j - 1];
                    ++cnt[j];
                }
            }
        }
    }
    print(cnt[m], '\n');
}

B,价值序列
 

先读懂题目,别把下标和项弄错。

利用数形结合的思想分析问题。先举例从例子入手分析最普遍的情况,然后再想复杂度最高,最特殊的情况。根据这两种情况设计算法。

将题目数学化。找规律,归纳,分为集合(划分成不同的部分分别处理)。

相等的数看成联通块。不同的情况不同的贡献用一个if else即可


p2[0]=1;
for(int i=1;i<N;i++) p2[i]=p2[i-1]*2%mod;    
for(int i=1;i<=n;i++)
    {
      int j=i;
      while(j<n&&a[j+1]==a[i]) j++;
 
      if(i-1>=1&&j+1<=n&&(a[i-1]<a[i]&&a[j+1]>a[i]||a[i-1]>a[i]&&a[j+1]<a[i]))
        ans=1ll*ans*p2[j-i+1]%mod;
      else ans=1ll*ans*(p2[j-i+1]+mod-1)%mod;
      i=j;
    }

思路无敌清晰 

void solve() {
    int n;
    std::cin >> n;
     
    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }
     
    Z ans = 1;
    std::vector<std::pair<int, int>> b;
    for (int i = 0, j = 0; i < n; i = j) {
        j = i;
        while (j < n && a[i] == a[j]) {
            j++;
        }
        b.emplace_back(a[i], j - i);
    }
     
    for (int i = 0; i < int(b.size()); i++) {
        if (i == 0 || i == int(b.size()) - 1 || (b[i] > b[i - 1]) == (b[i] > b[i + 1])) {
            ans *= power(Z(2), b[i].second) - 1;
        } else {
            ans *= power(Z(2), b[i].second);
        }
    }
     
    std::cout << ans.val() << "\n";
}

void work() {
    scan(n);
    pw[0] = 1;
    for(int i = 1; i <= n; ++i) scan(a[i]), pw[i] = pw[i - 1] * 2 % mod;    
    r[n] = n; for(int i = n - 1; i; --i)  r[i] = (a[i] == a[i + 1] ? r[i + 1] : i);
    int ans = 1;
    for(int i = 1; i <= n; i = r[i] + 1) {
        if(i == 1 || r[i] == n ||
           (a[i - 1] < a[i] && a[r[i]] > a[r[i] + 1]) ||
           (a[i - 1] > a[i] && a[r[i]] < a[r[i] + 1])) {
            ans = (ll)ans * ((pw[r[i] - i + 1] - 1 + mod) % mod) % mod;
        }
        else ans = (ll)ans * pw[r[i] - i + 1] % mod;
    }
    print(ans, '\n');
}
my shabby version :
		l[1] = 1;
		for(int i = 2; i<=n; i++){
			if(ar[i] == ar[i - 1])l[i] = l[i - 1]; if else用三木运算符更牛逼
			else l[i] = i;
		}
		
		for(int i = n; i >= 1; i = l[i] - 1){
			if(i == n || l[i] == 1 ||
				(ar[i] < ar[i + 1] && ar[l[i]] < ar[l[i] - 1] ) ||
				(ar[i] > ar[i + 1] && ar[l[i]] > ar[l[i] - 1] ))
				ans = (ll)ans * ((pw[i - l[i] + 1] - 1 + mod)%mod)%mod; 
		else{
			//(ans *= pw[i - l[i] + 1]%mod)%mod;
            必须先乘再%
               ans = ans * pw[i - l[i] + 1] % mod
		} 
	}

标签:std,int,++,牛客,寒假,ans,--,mod
来源: https://blog.csdn.net/IsayIwant/article/details/122945100

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有