一、Password
- 题目:给你一把密码锁,锁由4个0~9的数字组成,且是由两对相同的数字组成,给你锁中绝对不会出现的数字,问你这个锁有多少种方法可以组成
- 思路:数学,因为只有两个数字相同,数字选择一共有10 - n种选择,从中间选择两个,然后两个数字能够组成6种,再乘6就行
- 代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define int long long
#define pb push_back
#define endl '\n'
#define all(x) x.begin(),x.end()
#define PII pair<int,int>
using namespace std;
const int N = 2e5 + 100,mod=998244353;
int a[N];
vector<int> res;
void solve()
{
int n; cin >> n;
for(int i = 1;i <= n;i ++ ) cin >> a[i];
n = 10 - n;
cout << n * (n - 1) / 2 * 6 << endl;
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0);
int T; cin >> T;
while(T -- ) solve();
}
二、Permutation Value
- 题目:构造一个排列,使得这个排列中的子序列为排列的个数最少
- 思路:当n >= 2时,排列方法都是2,除了1,就是整体,所以搞一个这样的排列就行,把n放在1后面
- 代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define int long long
#define pb push_back
#define endl '\n'
#define all(x) x.begin(),x.end()
#define PII pair<int,int>
using namespace std;
const int N = 2e5 + 100,mod=998244353;
int a[N];
vector<int> res;
void solve()
{
int n; cin >> n;
for(int i = 1;i <= n;i ++ )
if(i == 1) cout << 1 << ' ';
else if(i == 2) cout << n << ' ';
else cout << i - 1 << ' ';
cout << endl;
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0);
int T; cin >> T;
while(T -- ) solve();
}
三、Permutation Value
- 题目:有n个箱子,每个箱子里面都有a[i]个报纸,有的箱子被抹布盖住,有的没有,问你执行操作以后,所有的抹布最多能够盖住多少张报纸
操作:每块抹布都可以移动,但是只能向左移动一格(0表示盒子没有被盖住,1相反) - 思路:每一段里面都找最后一个0出现的位置(因为只能向左移动一格),然后由后面一连串的1来判断是否需要向左移动,如果被盖住的盒子里面报纸的数量 < 0位置盒子里面的报纸数量的话,就让这一连串的1统一 向左移动一格(贪心),这样更优,便利一遍就行
- 代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define endl '\n'
#define all(x) x.begin(),x.end()
#define PII pair<int,int>
using namespace std;
const int N = 2e5 + 100,mod=998244353;
int a[N];
priority_queue<int> q;
void solve()
{
int n; cin >> n;
int sum = 0;
string s; cin >> s; s = "?" + s;
for(int i = 1;i <= n;i ++ ) cin >> a[i];
for(int i = 1;i <= n - 1;i ++ )
{
if(s[i] == '0' && s[i + 1] == '1')
{
int j = i + 1;
while(j <= n && a[j] >= a[i] && s[j] == '1')
{
j ++ ;
}
if(j <= n && a[j] < a[i])
{
swap(s[i],s[j]);
}
i = j - 1;
}
}
for(int i = 1;i <= n;i ++ )
if(s[i] == '1')
sum += a[i];
cout << sum << endl;
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int T; cin >> T;
while(T -- ) solve();
}
四、 Problem with Random Tests
- 题目:给你一个01串,问你哪两个字串与之后值最大?
- 思路:因为是随机数,所以暴力就行,首先题目要求最大,所以其中一个子串就是它本身,另一个串要满足其他的条件
- 条件1 :就是找到前面有1的第一个0的位置pos,比如000110011,位置就是6,然后每一次选取的字串长度必须是n - pos + 1,选取的范围是1
- 代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n; cin >> n;
string s; cin >> s; s = "?" + s;
int f = 0,pos = 1;
for(int i = 1;i <= n;i ++ )
{
if(s[i] == '1') f = 1;
if(f && s[i] == '0')
{
pos = i;
break;
}
}
string ans;
for(int i = pos;i <= n;i ++ )
ans += s[i];
int len = n - pos + 1;
for(int i = 1;i < pos;i ++ )
{
if(s[i] == '0') continue;
string res;
for(int j = i,k = pos; j <= i + len - 1;j ++,k ++)
if(s[j] == '1' || s[k] == '1')
res += "1";
else
res += "0";
ans = max(ans,res);
}
string u;
for(int i = 1;i < pos;i ++ )
u += s[i];
ans = u + ans;
ans = "?" + ans;
bool ff = false;
for(int i = 1;i < ans.size();i ++ )
{
if(ans[i] == '1') ff = true;
if(ff) cout << ans[i];
}
if(!ff) cout << "0" << endl;
else cout << endl;
return 0;
}