A Tokitsukaze and New Operation
按位模拟运算,然后字符串拼接即可。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;
const int N = 2e5 + 7;
const int mod = 1e9 + 7;
void solve(){
string a,b,res;
cin >> a >> b;
if (a.size() != b.size()){
cout << -1 << endl;
return;
}
auto n = a.size();
for (int i = 0; i < n;++i){
int x = a[i] - '0',y = b[i] - '0';
int t = x * y;
char u = t / 10 + '0';
char v = t % 10 + '0';
if (u == '0' && v == '0'){
res.push_back(u);
}else if(u == '0'){
res.push_back(v);
}else {
res.push_back(u);
res.push_back(v);
}
}
cout << res << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int _ = 1;cin>>_;
while(_--)
solve();
}
B Tokitsukaze and Order Food Delivery
最低消费有三种可能,即不用优惠卷,用一张优惠卷,用两张优惠卷。 可以直接二分去寻找答案,比较最小值就可以了。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;
const int N = 2e5 + 7;
const int mod = 1e9 + 7;
void solve(){
ll n,a,b;cin >> n >> a >> b;
ll res = 1e9;
for (int i = 1; i <= n; ++i){
ll k,x,y;cin >> k >> x >> y;
vector<int> d;
d.clear();
for (int j = 1; j <= k; ++j){
int v;cin >> v;
d.push_back(v);
}
sort(d.begin(),d.end());
ll t1 = d[0];
auto s2 = lower_bound(d.begin(),d.end(),x);
ll t2 = 1e12;
if (s2 != d.end()){
t2 = *s2;
}
auto s3 = lower_bound(d.begin(),d.end(),a);
ll t3 = 1e12;
if (s3 != d.end()){
t3 = *s3;
}
ll t4 = 1e12;
if (a < x){
t4 = min(t2 - b - y,t3 - b);
t4 = max(0ll,t4);
}else{
t4 = min(t3 - b - y,t2 - y);
t4 = max(0ll,t4);
}
t1 = min(t1,t4);
t1 = max(0ll,t1);
res = min(t1,res);
}
cout << res << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int _ = 1;cin>>_;
while(_--)
solve();
}
C Tokitsukaze and Average of Substring
直接暴力模拟左右端点,可以用哈希表去记录出现的对数。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;
const int N = 1e4 + 7;
const int mod = 1e9 + 7;
char a[N];
void solve(){
int n;cin >> n;
double res = 0;
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 1; i <= n; ++i) {
unordered_map<char,int> d;
double t = 0;
for (int j = i ; j <= n; ++j) {
if (d[a[j]] + 1 >= 2){
t += d[a[j]]++;
}else{
d[a[j]]++;
}
res = max(res,t / (j - i + 1));
}
}
printf("%.15lf\n",res);
}
int main() {
//ios::sync_with_stdio(false);
//cin.tie(nullptr),cout.tie(nullptr);
int _ = 1;cin>>_;
while(_--)
solve();
}
D Tokitsukaze and Development Task
直接bfs求10到300以内所以数的最短次数即可。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;
const int N = 1e4 + 7;
const int mod = 1e9 + 7;
int dx[] = {1,-1,100,-100,300,-300,10,-10};
int a[N];
int dist[N];
void dfs(){
queue<int> q;
memset(dist,-1,sizeof(dist));
q.push(10);
dist[10] = 0;
while(!q.empty()){
int x = q.front();
q.pop();
for(int i = 0;i < 8;++i){
int u = x + dx[i];
u = min(300,u);
u = max(10,u);
if (dist[u] != -1)continue;
dist[u] = dist[x] + 1;
q.push(u);
}
}
}
void solve(){
int res = 0;
for (int i = 1; i <= 4; ++i)cin >> a[i],res += dist[a[i]];
cout << res << endl;
}
int main() {
//ios::sync_with_stdio(false);
//cin.tie(nullptr),cout.tie(nullptr);
int _ = 1;cin>>_;
dfs();
while(_--)
solve();
}
E Tokitsukaze and Colorful Chessboard
可以发现,对于n n的棋盘而言,要上下左右四个方向不出现相同的元素,存在一种最优解是max(n n / 2 , n n - n n / 2),所以我们可以先预处理出对于所以的n,他的最优解是多少,与max(a,b)比较,当大于时我们即可跳出比较,如果min(a,b) 大于min(n n / 2 , n n - n n / 2)时,我们对n+1即可,为什么呢 ? 因为n n / 2 , n n - n n / 2 最多相差1,或者0,我们当n为偶数时会相等,n为奇数时会相差1,其实就是在放置到最后一排时少放了一个,因为为奇数要差一位。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;
const int N = 1e4 + 7;
const int mod = 1e9 + 7;
vector<ll> c;
void solve(){
ll a,b;cin >> a >> b;
ll t = max(a,b);
auto s = lower_bound(c.begin(),c.end(),t) - c.begin();
if (s * s / 2 < min(a,b))s++;
cout << s << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
for (int i = 0; i <= 100000; ++i){
if (1ll * i * i / 2 == i * i - 1ll * i * i / 2)
c.push_back(1ll * i * i / 2);
else
c.push_back(1ll * i * i / 2 + 1);
}
int _ = 1;cin>>_;
while(_--)
solve();
}
F Tokitsukaze and New RenKinKama
题目要求最多换两次,那么在最优情况下是我们一次交换最多会让6个坏点变成好点,i - 1, i , i + 1 , j - 1 , j , j + 1。所以在坏点数量大于12时是无解的。当坏点数量大于6时是无法通过一次交换满足条件的,所以我们可以模拟坏点与其余点的交换,然后再模拟交换后的坏点与其余点的交换,因为很显然好点与好点的交换是无意义的,所以我们模拟坏点与其余点的交换。在最后判断的时候,你可以选择再寻找一次坏点,如果为0那么为答案,你也可以选择更优解,那便是你只需要看看第二次的坏点与交换的那个点是不是为坏点即可,这样子显然是更优的。因为坏点至多6个。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;
const int N = 1e3 + 7;
const int mod = 1e9 + 7;
int n,k;
int a[N];
bool check(vector<int> bed2,int m){
bed2.push_back(m);
for (auto x : bed2){
if (abs(a[x] - a[(x + 1) % n]) > k)return false;
if (abs(a[x] - a[(x - 1 + n) % n]) > k)return false;
}
return true;
}
vector<int> find_bed(){
vector<int> res;
for (int i = 0; i < n; ++i){
if (i == 0){
if (abs(a[n - 1] - a[i]) > k){
res.push_back(n - 1) , res.push_back(i);
}
}else{
if (abs(a[i - 1] - a[i]) > k){
if ( res.empty() || res.back() != i - 1)
res.push_back(i - 1);
res.push_back(i);
}
}
}
return res;
}
void solve(){
cin >> n >> k;
for (int i = 0 ;i < n; ++i)
cin >> a[i];
vector<int> bed1,bed2;
if (n == 1){
cout << 0 << endl;
return;
}
bed1 = find_bed();
if (bed1.empty()){
cout << 0 << endl;
return;
}
if (bed1.size() > 12){
cout << -1 << endl;
return;
}
for (auto i : bed1) {
for (int j = 0; j < n; ++j){
if (i == j)continue;
swap(a[i],a[j]);
bed2 = find_bed();
if (bed2.size() == 0){
cout << 1 << endl;
cout << i + 1 << " " << j + 1 << endl;
return;
}
if (bed2.size() > 6){
swap(a[i],a[j]);
continue;
}
for (auto l : bed2){
for (int m = 0; m < n; ++m) {
if (l == m)continue;
swap(a[l],a[m]);
if (check(bed2,m)){
cout << 2 << endl;
cout << i + 1 << " " << j + 1<< endl;
cout << l + 1<< " " << m + 1<< endl;
return;
}
swap(a[l],a[m]);
}
}
swap(a[i],a[j]);
}
}
cout << -1 << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int _ = 1;cin>>_;
while(_--)
solve();
}