A - T-shirt
- 思路
- 要么一定得到,要么不可能得到,要么按题意概率直接列公式算概率
- 经验教训
- 无
- AC代码
#define int long long
void solve() {
int a,b,c,x;
cin>>a>>b>>c>>x;
cout<<fixed<<setprecision(9);
if (x<=a) cout<<1<<'\n';
else if (x>b) cout<<0<<'\n';
else{
// double ans = 0;
//cout<<111;
cout<<(double)c/(b-a)<<'\n';
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
solve();
}
B - Minimize Ordering
- 思路
- 字典储存个数,然后按字典序从小到大打印即可
- 经验教训
- 无
- AC代码
#define int long long
void solve() {
string s;
cin>>s;
map<char,int> m;
for (int i = 0; i < s.size(); ++i) {
m[s[i]]++;
}
string ans;
for (auto mm:m) {
for (int i = 0; i < mm.second; ++i) {
ans+=mm.first;
}
}
cout<<ans;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
solve();
}
C - 1111gal password
- 思路
- 本来以为挺难的,其实就是个dp
- dp[n][k]表示一共有n个数字时,最高位数字是k时,所以能组出来的排序数
- dp递推公式看代码应该很快就能看懂,比如2xxx所能组成的符合题意排序个数就会等于1xx+2xx+3xx。而1和9比较特殊,1xxx=1xx+2xx;9xxx=9xx+8xx。
- 初始化n=2的情况即可
- 记得随时取模
- 经验教训
- 无
- AC代码
#define int long long
const int maxn = 1e6 + 5;
int dp[maxn][10];
int mod = 998244353;
void solve() {
int n;
cin >> n;
dp[2][1] = 2;
for (int i = 2; i <= 8; ++i) {
dp[2][i] = 3;
}
dp[2][9] = 2;
for (int i = 3; i <= n; ++i) {
for (int j = 1; j <= 9; ++j) {
if (j == 1) dp[i][j] = (dp[i - 1][1] + dp[i - 1][2]) % mod;
else if (j == 9) dp[i][j] = (dp[i - 1][8] + dp[i - 1][9]) % mod;
else dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j] + dp[i - 1][j + 1]) % mod;
}
}
int ans = 0;
for (int i = 1; i <= 9; ++i) {
ans+= (dp[n][i])%mod;
}
cout<<(ans)%mod;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
solve();
}
D - ABC Transform
-
思路
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rW3LhmrS-1646546097921)(https://secure2.wostatic.cn/static/jADJCBj9nMgvfojZB1w8Zs/image.png)]
- 整个搜索过程看成是一个类似二叉树的东西,每一层代表经过t次变化后得到的结果。0代表A,1代表B,2代表C。每一层的第k个位置通过(k+1)/ 2可以找到他的父节点,一层一层上去最终找到最初的。
- 如果设m为从最初走到最后的一层的第k个位置所经过的数之和(每一层+1或者+2),那么(最初位置的数+m)%3就是最后的答案
-
经验教训
- (k%2)^1: ^1的效果为1变成0,0变成1
-
AC代码
#define int long long
const int maxn =1e5+5;
int a[maxn];
//void solve(string &s) {
//
//}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
string s;int q;
cin>>s>>q;
for (int i = 0; i < s.size(); ++i) {
if (s[i] =='A' ) a[i+1] = 0;
if (s[i] =='B' ) a[i+1] = 1;
if (s[i] =='C' ) a[i+1] = 2;
}
map<int,char> m;
m[0] = 'A',m[1]='B',m[2] = 'C';
for (int i = 0; i < q; ++i) {
int t,k;cin>>t>>k;
int sum = 0;
while (t>0 && k!=1){
sum += ((k%2)^1)+1;
sum%=3;
k = (k+1)/2;
t--;
}
sum+=t;
cout<<m[(a[k]+sum)%3]<<'\n';
}
}
E - (∀x∀)
- 思路
- 我们可以首先预处理出长度为n的串所构成的全部回文串个数,比如长度为1,那么就只能是A,B…,Z一共26个,长度为2,AA,BB,…ZZ一共26个,长度为3,A?A,B?B…Z?Z,其中?可以为长度为1的回文串个数,所以一共为26*26个,以此类推下去
- 以串CBDDD举例,我们可以知道AxxxA,BxxxB对应的所有情况一定是合法,所以我们首先得到 ( i n t ) C − A (int) C-A (int)C−A* 长度为3的回文串个数(2626),即ans+=226*26。走到B,我们知道AxA对应的所有情况一定是合法的,所以 ans+= ((int)B-A)*26。然后走到最中间,特判CBDBC是否合法,如果合法就+1,不合法就不+1,输出ans即可
- 经验教训
- 无
- AC代码
#define int long long
const int maxn = 1e6 + 5;
int dp[maxn];
int mod = 998244353;
void pre() {
dp[0] = 1;
for (int i = 1; i <= 1000000; ++i) {
dp[i] = (dp[i - 1] * 26) % mod;
}
}
void solve() {
string s;
int n;
cin >> n >> s;
if (n==1){
cout<<(s[0]-'A')+1<<'\n';
return;
}
int ans = 0;
if (s.size() % 2 == 0) {
int len = s.size() / 2 - 1;
for (int i = 0; i < s.size() / 2; ++i) {
int me = s[i] - 'A';
ans += (me * dp[len] % mod);
ans %= mod;
len--;
}
} else {
int len = (s.size()) / 2;
for (int i = 0; i < s.size() / 2 + 1; ++i) {
int me = s[i] - 'A';
// cout<<dp[len]<<" "<<len<<" "<<me*dp[len]<<endl;
ans += ((me * dp[len]) % mod);
ans %= mod;
len--;
}
}
int ret = ans % mod;
int left, right;
if (n % 2) {
left = n / 2 - 1, right = n / 2 + 1;
} else {
left = n / 2 - 1, right = n / 2;
}
while (s[left] == s[right] && left > 0) {
left--;
right++;
}
if (s[left] <= s[right]) ret++;
cout << ret << '\n';
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
cin >> t;
pre();
for (int i = 0; i < t; ++i) {
solve();
}
}