2023杭电第二场补题报告1001 1002 1004 1007 1009

2023杭电第二场补题报告1001 1002 1004 1007 1009

1001 Alice Game (hdu.edu.cn)

思路

题目比较难读,读完题其实就不是很难了,很明显是一个nim游戏的变体,难的地方在于要写出sg函数然后打表找规律,最后ac代码就几行。

代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second

using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n,k;
int a[N];

void solve() {
  cin >> k >> n;
  if (((n - 2) % (4 * k + 2) == k - 1 && n > k) || n == 0)
    cout << "Bob\n";
  else
    cout << "Alice\n";
}

signed main() {
  IOS;
  int t = 1;
  cin >> t;
  for (int i = 1; i <= t; i++) {
    solve();
  }
}

1002 Binary Number (hdu.edu.cn)

思路

直接贪心,因为翻转一连串01串将其变成全1的次数其实就是连续0的段数。所以我们为了让字典序尽可能大,首先要数出从前往后一共有多少连续0的子段,如果子段数小于等于k,那就尽可能先翻转前面的再反转后面的。如果有剩余,我们发现只要不是全1串或者是全1串但是操作次数不为1且全1串长度不为1,都可以变成全1,剩下的就只能让末位变0。

代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second

using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n, k;
int a[N];

void solve() {
  string s;
  cin >> n >> k;
  cin >> s;
  int l = -1;
  bool ok = 0;
  for (int i = 0; s[i]; i++) {
    if (s[i] == '0') {
      if (l == -1) l = i;
    } else {
      if (l != -1) k--, ok = 1;
      if (k == 0) {
        for (int j = 0; j < i; j++) cout << "1";
        for (int j = i; j < n; j++) cout << s[j];
        cout << "\n";
        return;
      }
      l = -1;
    }
  }
  if (l > 0) k--, ok = 1;
  if ((k && ok) || !k) {
    for (int i = 0; i < n; i++) cout << '1';
    cout << "\n";
  } else if (k % 2) {
    if (k == 1 || n == 1) {
      for (int i = 0; i < n - 1; i++) cout << '1';
      cout << "0\n";
    } else {
      for (int i = 0; i < n; i++) cout << '1';
      cout << "\n";
    }
  } else {
    for (int i = 0; i < n; i++) cout << '1';
    cout << "\n";
  }
}

signed main() {
  IOS;
  int t = 1;
  cin >> t;
  for (int i = 1; i <= t; i++) {
    solve();
  }
}

1004 Card Game (hdu.edu.cn)

思路

打表手动模拟然后猜结论,严谨证明过于复杂。。。

代码

#include <bits/stdc++.h>
#define int long long
#define ll long long
#define endl '\n'
#define P pair<int,int>
#define FOR(i,n) for(int i = 1;i <= n;i ++)  
using namespace std;
 
const int N = 2e5 + 10;
const int mod = 998244353;
const int INF = 0x3f3f3f3f3f3f3f;
int n,m,x,y,t,k,a[N];

int qpow(int a,int b)
{
    int ans=1;
    while(b){
        if(b&1)
            ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}

void solve() {
	cin >> n;
	cout << (qpow(2,n-1) - 1 + mod) % mod << endl; 
}

signed main() {
    ios_base::sync_with_stdio(0),cin.tie(0);
    cin >> t;
    while(t--) solve(); 
    return 0;
}

1007 foreverlasting and fried-chicken (hdu.edu.cn)

思路

很像去年杭电多校的火柴人计数,但是需要加入bitset优化,这样复杂度就是 n 3 32 \frac{n^3}{32} 32n3,就跑的飞快,比较坑的是注意组合数的时候在记录上面两个分叉的时候有可能i,j两点之间也有边相连也计入了。

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve();
void init();
signed main() {
  cin.sync_with_stdio(0);
  cin.tie(0);
  int T = 1;
  cin >> T;
  init();
  while (T--) {
    solve();
  }
  return 0;
}
#define N 1010
#define mod 1000000007
int fac[N];
int inv[N];
int qpow(int a, int p) {
  int r = 1;
  while (p) {
    if (p & 1) {
      (r *= a) %= mod;
    }
    (a *= a) %= mod;
    p >>= 1;
  }
  return r;
}
void init() {
  fac[0] = 1;
  for (int i = 1; i < N; i++) {
    fac[i] = fac[i - 1] * i % mod;
    assert(fac[i] > 0);
  }
  inv[N - 1] = qpow(fac[N - 1], mod - 2);
  for (int i = N - 2; i >= 0; i--) {
    inv[i] = inv[i + 1] * (i + 1) % mod;
    assert(inv[i] > 0);
  }
}
int C(int m, int n) {
  if (n > m)
    return 0;
  else
    return fac[m] * inv[m - n] % mod * inv[n] % mod;
}
vector<int> g[N];
int k[N][N];
int exi[N][N];
void solve() {
  int n;
  cin >> n;
  bitset<N> bt[n + 1];
  for (int i = 1; i <= n; i++) {
    g[i].clear();
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      k[i][j] = 0;
      exi[i][j] = 0;
    }
  }
  int m;
  cin >> m;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
    bt[u].set(v, true);
    bt[v].set(u, true);
  }
  for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
      k[i][j] = (bt[i] & bt[j]).count();
    }
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
      int f = 0;
      if (bt[i][j]) {
        f = 1;
      }
      ans += C(k[i][j], 4) *
             (C(g[i].size() - 4 - f, 2) + C(g[j].size() - 4 - f, 2) % mod) %
             mod;
      ans %= mod;
    }
  }
  cout << ans << "\n";
}

1009 String Problem (hdu.edu.cn)

思路

如果要求回文串含不止一种字母其实可能还很复杂,但是由于只含一种字母,所以只需要找连续的相同字符串即可,对于其他的,直接当做长度为1的并不影响结果(+1-1)。

代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second

using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n;
int a[N];

void solve() {
  string s;
  cin >> s;
  int l = 0;
  int k = 0;
  for (int i = 0; s[i]; i++) {
    if (s[l] == s[i])
      continue;
    else {
      k++;
      l = i;
    }
  }
  k++;
  cout << s.length() - k << "\n";
}

signed main() {
  IOS;
  int t = 1;
  cin >> t;
  for (int i = 1; i <= t; i++) {
    solve();
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值