codeforces比赛记录
(一).Problem I. Subnet
思路:
这段代码实现了一个简单的 IP 地址匹配器。它的主要功能是判断一个给定的 IP 地址是否匹配一个给定的子网掩码。下面是代码的思路:
1.split 函数:该函数用于分割字符串,将以特定字符为分隔符的子字符串存储到数组中。在这里,它用于将 IP 地址和子网掩码按照点号和斜杠分割成对应的部分。
2.bbs 函数:该函数将 IP 地址转换成二进制形式的 bitset。它首先调用 split 函数将 IP 地址按点号分割成四部分,然后将每个部分转换为整数,再将每个整数转换为对应的 8 位二进制数,最后将这 4 个 8 位二进制数组合成一个 32 位的 bitset。
3.judge 函数:该函数用于判断一个 IP 地址是否匹配一个子网掩码。它首先调用 split 函数将传入的子网掩码字符串按斜杠分割成 IP 地址和掩码位数两部分。然后,它调用 bbs 函数将 IP 地址和子网掩码都转换成对应的 bitset。接着,它比较前 pp 位是否相同,如果有不同的位,则返回 false,表示不匹配;如果所有位都相同,则返回 true,表示匹配。
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
void split(string& s, char dd, string* ts) {
int tt = 0;
int st = 0;
for (size_t i = 0; i < s.size(); ++i) {
if (s[i] == dd) {
ts[tt++] = s.substr(st, i - st);
st = i + 1;
}
}
ts[tt] = s.substr(st, s.size() - st);
}
bitset<32> bbs(string& ip) {
string ts[4];
split(ip, '.', ts);
bitset<32> bi;
for (int i = 0; i < 4; ++i) {
int ot = stoi(ts[i]);
for (int j = 7; j >= 0; --j) {
bi.set(i * 8 + (7 - j), (ot >> j) & 1);
}
}
return bi;
}
bool judge(string& ss,string& ip) {
string ts[2];
split(ss, '/', ts);
string si = ts[0];
int pp = stoi(ts[1]);
bitset<32> sbs = bbs(si);
bitset<32> ibs = bbs(ip);
for (int i = 0; i < pp; ++i) {
if (sbs[i] != ibs[i]) {
return false;
}
}
return true;
}
int main() {
string ss;
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
string ip;
if (judge(ss, ip)) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
return 0;
}
(二).B. Chaya Calendar
思路:
加上每两个时间之间的间隔
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
#define N 2000005
#define mod 7777777
typedef long long ll;
ll n, m, t, cnt, ans, num1, num2, num3, maxx;
ll x, y;
ll a[N], b[N],c[N];
char s[N];
bool vis[N];
map<int, int>k, dis;
vector<int>dp2, dp3;
int gcd(int a, int b) {
return b > 0 ? gcd(b, a % b) : a;
}
ll judge(ll x,ll y) {
ll z = 0;
for (int i = 1; i <= 1000000; i++) {
if (y * i >= x) {
z = y * i;
break;
}
}
return z;
}
int main()
{
cin >> t;
void solve();
while (t--) {
solve();
}
return 0;
}
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
ans = 0;
for (int i = 1; i <= n; i++) {
ans += a[i] - ans % a[i];
}
cout << ans << endl;
}
(三).C. LR-remainders
思路:
求最后删去的那个元素对m的取余,再乘上前一次被删除的元素,再对m取余就是倒数第二个答案。最后把答案反向输出即可。
#include<iostream>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N = 200010;
const int M = 500010;
const int inf = 1234567890;
ll a[N], b[N];
void solve()
{
ll n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
string s;
cin >> s;
ll k = n, L = 0, R = n+1;
for (int i = 0; i <n; i++)
{
if (s[i] == 'L')
{
L++;
b[n-i] = a[L];
}
else
{
R--;
b[n-i] = a[R];
}
}
ll ans = 1;
vector<ll>q;
for (int i = 1; i <= n; i++)
{
ans = (ans * b[i]) % m;
q.push_back(ans);
}
for (int i = n-1; i >= 0; i--)
{
cout << q[i] << " ";
}
cout << "\n";
}
int main()
{
ll t;
cin >> t;
while (t--) solve();
return 0;
}