A. Dislike of Threes
题意:给出一组从1开始的数,要求不包括3的倍数或个位是3的数,给出n,输出第n个数
数据范围n <= 1000
分析:暴力
代码:
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1e9 + 7;
int n, m, t, k;
int s[N], g[N], dp[N];
vector<int> vec;
void solve()
{
int i = 0;
while (vec.size() < 1010)
{
i++;
if (i % 10 != 3) vec.push_back(i);
i++;
if (i % 10 != 3) vec.push_back(i);
i++;
}
cin >> n;
while (n--)
{
int a;
cin >> a;
cout << vec[a - 1] <<endl;
}
}
int main()
{
t = 1;
// cin >> t;
while(t--)
solve();
return 0;
}
B. Who's Opposite?
题意:对于一个长度为2n的序列,按1到2n围成圈,x<n时,x与x+n相对,询问给出a,b,c,假如a与b相对,问与c相对的是多少,不合法输出-1
分析:对于给出的a,b显然差值为总数的一半,可以算出总数为多少,合法性可以探究a,b,c的位置,显然a,b中值大的须在后一半,值小的须在前一半,c需要在总数内部,非法输出-1,合法根据c的位置加或减总数一半即可
代码:
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1e9 + 7;
int n, m, t, k;
int s[N], g[N], dp[N];
void solve()
{
int a, b, c, d, e, d1;
cin >> a >> b >> c;
if (a < b) swap(a, b);
e = (a - b) * 2;
if (a <= e / 2 || a > e)
{
puts("-1");
return;
}
if (b > e / 2)
{
puts("-1");
return;
}
if (c > e)
{
puts("-1");
return;
}
d = (c + e / 2 - 1) % e + 1;
printf("%d\n", d);
}
int main()
{
t = 1;
cin >> t;
while(t--)
solve();
return 0;
}
C. Infinity Table
题意:将所有数从1开始的正整数排列,排列方式为从(1,i)依次往下放,直到(i,i)再往左依次放置,直到(i,1),i++,循环
分析:对于(i,1),都是\(i^{2}\),就可以直接找到小于目标数的根号的行列数,然后倒回去即可,且因为放置规律,可以直接算出来,令\(m^{2}\)为n以下最大的平方数,如果n-\(m^{2}\)<m+1,位置就是{n-\(m^{2}\),m+1}, 否则位置是{m+1,\(m^{2}\)-2m-n}。
代码:
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1e9 + 7;
int n, m, t, k;
int s[N], g[N], dp[N];
void solve()
{
cin >> n;
m = sqrt(n);
if (m * m == n)
{
printf("%d %d\n", m, 1);
return;
}
k = n - m * m;
if (k <= m + 1) printf("%d %d\n", k, m + 1);
else printf("%d %d\n", m + 1, (m + 1) * (m + 1) - n + 1);
}
int main()
{
t = 1;
cin >> t;
while(t--)
solve();
return 0;
}
D. Make a Power of Two
题意:对于给出的数(n<1e9),有两种操作 1:删除十进制中某一位,2:在末尾任意加一位,使得最终数字为2的幂次方,且不允许包含前导零,问操作数最少数值
分析:显然操作数最多为10,所有数都删除,最后加1,初步分析可知数据量很小,考虑暴力,对于2的幂次方,int范围内32个,long long范围内64个,考虑到操作有加有减,我们暴力处理64个数据,对于每个数据都与n进行匹配,找出至少需要删除多少元素,添加多少元素可以变成这一类的2得幂次方,所有情况答案取最小即可
代码:
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1e9 + 7;
const ll INF = 1e18;
int n, m, t, k;
int s[N], g[N], dp[N];
vector<ll> vec, vec1, vec2;
int check(int a, ll b)
{
int a1 = a;
ll b1 = b;
int cnt = 0;
vec1.clear();
vec2.clear();
while (a)
{
vec2.push_back(a % 10);
a /= 10;
}
while (b)
{
vec1.push_back(b % 10);
b /= 10;
}
reverse(vec2.begin(), vec2.end());
reverse(vec1.begin(), vec1.end());
cnt = vec2.size();
int i, j;
for (i = 0, j = 0; i < vec1.size() && j < vec2.size(); j++)
if (vec1[i] == vec2[j])
i++, cnt--;
if (i == vec1.size()) return cnt;
return cnt + vec1.size() - i;
}
void solve()
{
ll cnt = 1;
while (cnt * 2 < INF) vec.push_back(cnt), cnt *= 2;
cin >> n;
while (n--)
{
cin >> k;
int ans = 30;
for (int i = 0; i < vec.size(); i++)
{
ans = min(ans, check(k, vec[i]));
}
cout << ans << endl;
}
}
int main()
{
t = 1;
// cin >> t;
while(t--)
solve();
return 0;
}
E. Polycarp and String Transformation
题意:对于一个初始字符串s和一个空字符串t,我们以此对s进行如下操作 1.将s添加到t之后 2.选择s中的一类字母,从s中去除,上述操作执行到s为空,给出t数组,问原s数组,以及删除字母顺序,如果给出的t不可能存在s,输出-1
分析:根据删除情况,显然之前删除过得后续不会出现,那么倒着找最新出现的元素就是删除的元素,这里知道了如果存在s,s的字母删除顺序,假设字母类型数为n,那么第i个删除的意味着t中s的该元素进行了i轮,如果t中该元素数量不能整除i那么不会合法,否则你可以得到一个当前的原数组s,按照删除顺序走一遍,看看会不会变成t,如果不是t,那么依然不合法,合法就输出答案即可
代码:
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1e9 + 7;
int n, m, t, k;
int s[N], g[N], dp[N];
void solve()
{
string a;
string b;
string c;
string d;
cin >> a;
for (int i = 0; i < 26; i++) g[i] = 0;
for (int i = a.size() - 1; i >= 0; i--)
{
if (g[a[i] - 'a'] == 0) b += a[i];
g[a[i] - 'a']++;
}
reverse(b.begin(), b.end());
int ans = 0;
for (int i = 0; i < b.size(); i++)
if (g[b[i] - 'a'] % (i + 1))
{
puts("-1");
return;
}
else ans += g[b[i] - 'a'] / (i + 1);
for (int i = 0; i < ans; i++)
c += a[i], d += a[i];
for (int i = 0; i < b.size(); i++)
{
g[b[i] - 'a'] = 0;
for (int j = 0; j < c.size(); j++)
if (g[c[j] - 'a'])
d += c[j];
}
if (a != d)
{
puts("-1");
return;
}
cout << c << ' ' << b << endl;
}
int main()
{
t = 1;
cin >> t;
while(t--)
solve();
return 0;
}
F. Nearest Beautiful Number
题意:f1与f2区别不大,f1中k<2,f2中k<11,这里直接讲f2,给出n和k,问大于等于n的,数字不同的种类数不超过k的数最小是多少。
分析:对于要求的数最小,那么高位的数要尽可能不变,所以对于给定的数从高位到低位去以此判断,如果当前数字被用过就直接跳过,如果没被用过那就看看当前种类数够不够,不够的话,就把这个数填进去,如果种类数也用够了,那就看看能不找到比这个数大的用过的数,找到的话当前就直接改这个数,后续的数填任意数都可用保证符合答案,考虑到种类数,填选过的最小值填满就好,不然那就要去改变前一位的状态,如果前一位是唯一新数,那么就可以直接+1,保证大后,判断当前有没有种类数,如果刚刚那位+1后的值是用过的数,那么就有一个种类数,定为0,后续补满0即可,如果不是,那后续就补满已经选过的数的最小值,如果不是唯一新数,就看有没有选过的数比这个数大的,有的话就跟刚刚一样,没有的话,可以再往回找即可。
代码:
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1e9 + 7;
int n, m, t, k;
int s[N], g[N], dp[N];
vector<int> vec, vec1;
void solve()
{
for (int i = 0; i < 10; i++) g[i] = 0;
vec.clear(), vec1.clear();
cin >> n >> k;
int minn = 10;
while (n) vec.push_back(n % 10), n /= 10;
reverse(vec.begin(), vec.end());
k--;
g[vec[0]] = 1;
minn = vec[0];
vec1.push_back(vec[0]);
for (int i = 1; i < vec.size(); i++)
{
if (g[vec[i]])
{
vec1.push_back(vec[i]);
continue;
}
else if (k)
{
k--;
g[vec[i]] = i + 1;
minn = min(vec[i], minn);
vec1.push_back(vec[i]);
}
else
{
for (int j = vec[i] + 1; j <= 9; j++)
{
if (g[j])
{
vec1.push_back(j);
for (int k = i + 1; k < vec.size(); k++)
vec1.push_back(minn);
for (int k = 0; k < vec1.size(); k++)
printf("%d", vec1[k]);
puts("");
return;
}
}
while (g[vec1[vec1.size() - 1]] != vec1.size())
{
for (int j = vec1[vec1.size() - 1] + 1; j <= 9; j++)
{
if (g[j])
{
vec1.pop_back();
vec1.push_back(j);
for (int k = vec1.size(); k < vec.size(); k++)
vec1.push_back(minn);
for (int k = 0; k < vec1.size(); k++)
printf("%d", vec1[k]);
puts("");
return;
}
}
vec1.pop_back();
}
int a = vec1[vec1.size() - 1];
vec1[vec1.size() - 1]++;
if (minn == a) minn++;
if (g[a + 1]) minn = 0;
for (int k = vec1.size(); k < vec.size(); k++)
vec1.push_back(minn);
for (int k = 0; k < vec1.size(); k++)
printf("%d", vec1[k]);
puts("");
return;
}
}
for (int k = 0; k < vec1.size(); k++)
printf("%d", vec1[k]);
puts("");
}
int main()
{
t = 1;
cin >> t;
while(t--)
solve();
return 0;
}