前言
第一次打四题的周赛,有点怕,先写了两题没交,观望第三题,发现好像不难(观察大法),遂直接交题,猛攻c,最后总方案数,思路一直理不清,只能拿个基本分走了,D题也是,找规律花了不少时间,最后也没推出了,只能赛后补题了-_-
ai✌已经能AC掉 ABD和大部分C,感觉自己已经没有存在的必要了(-_-)
把D题给补了,感觉很不好搞,勉强看懂解析,升级之路漫漫又长长啊 ---9.24
A. Letter Song ~ 致十年后的我们
基本题,用了最捞的做法
void solve() {
string s;
cin>>s;
int ans = 0;
for(int i=0;i<4;i++){
ans = ans*10 + (s[i]-'0');
}
cout<<ans+10;
for(int i=4;i<s.length();i++){
cout<<s[i];
}
}
B 简单图形问题 - 0123
手搓一下,发现等腰三角形肯定造不出来,所以不是0就是3,判断一下是不是正方形就可以了
int check(int u){
int n = sqrt(u);
if(n*n==u){
return 1;
}
else{
return 0;
}
}
void solve() {
LL s;
cin>>s;
if(check(s)){
cout<<0<<endl;
}
else{
cout<<3<<endl;
}
}
C 小红的机器人构造 - Ⅰ+Ⅱ+Ⅲ
超绝题目,前面做得还可以,就是对删除点的判断思路没理清,赛后写了快3000行才冲下来,分类讨论分麻了
思路: 先把目标坐标的点先存入一个a(5,0)的数组,然后字符串s存入b(5,0)的数组,然后对比,不符合条件的(比如对于目标坐标的硬性长度都没有的,自然不可能到达(x,y))这一步就可以直接输出NO
然后对于多出来的坐标值,我用c(5,0)存入,然后遍历s,控制c来控制输出,这样第二个样例也达成了,输出的字符一定符合条件。
最后就是数量的判断,可以进行分组对于UD和RL,我们发现,对于对出来的值,可以往a上面加,反正最后是抵消的,所以可以遍历还能加的值,再判断另一个值的上限,不要超过了,利用组合数求乘积再求和,最后UD和RL的方案求乘积,还要注意取mod,细节还是挺多的。
贴一手史山
0 1 2 3
U L D R
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
typedef long long int LL;
const int N = 2e5 + 5;
const int mod = 1e9 + 7;
const int p = 1e9+7;
int64_t fact[N];
int64_t pw(int64_t a, int64_t b) {
int64_t r = 1;
while(b > 0) {
if(b & 1) r = (r * a) % mod;
b /= 2;
a = (a * a) % mod;
}
return r;
}
int64_t C(int64_t n, int64_t k) {
if(n < k) return 0LL;
return (fact[n] * pw((fact[n - k] * fact[k]) % mod, mod - 2)) % mod;
}
void solve() {
int n,x,y;
cin>>n>>x>>y;
string s;
cin>>s;
vector<LL> a(5,0);
if(x>0){
a[0]+=x;
}
else {
a[2]+=abs(x);
}
if(y>0){
a[3]+=y;
}
else {
a[1]+=abs(y);
}
vector<LL> b(5,0);
for(int i=0;i<s.length();i++){
if(s[i]=='U'){
b[0]++;
}
else if(s[i]=='L'){
b[1]++;
}
else if(s[i]=='D'){
b[2]++;
}
else if(s[i]=='R'){
b[3]++;
}
}
int op = 0;
for(int i=0;i<4;i++){
if(a[i]>b[i]){
op=1;
}
}
if(op==1){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<" ";
vector<LL> c(5,0);
for(int i=0;i<4;i++){
if(a[i]<b[i]){
c[i]+=(b[i]-a[i]);
}
}
LL ans = 0,sum = 0;
if(a[0]>=a[2]){
int kk = a[0] - a[2];
for(int i=kk;i<=b[0];i++){
if(i-kk<=b[2]) ans = (ans+(C(b[0],i)*C(b[2],i-kk))%p)%p;
}
}
else{
int kk = a[2] - a[0];
for(int i=kk;i<=b[2];i++){
if(i-kk<=b[0]) ans = (ans+(C(b[2],i)*C(b[0],i-kk))%p)%p;
}
}
if(a[1]>=a[3]){
int kk = a[1] - a[3];
for(int i=kk;i<=b[1];i++){
if(i-kk<=b[3]) sum = (sum+(C(b[1],i)*C(b[3],i-kk))%p)%p;
}
}
else{
int kk = a[3] - a[1];
for(int i=kk;i<=b[3];i++){
if(i-kk<=b[1]) sum = (sum+(C(b[3],i)*C(b[1],i-kk))%p)%p;
}
}
ans = (ans*sum)%p;
for(int i=0;i<n;i++){
if(s[i]=='U'){
if(c[0]){
c[0]--;
}else{
cout<<s[i];
}
}
else if(s[i]=='L'){
if(c[1]){
c[1]--;
}else{
cout<<s[i];
}
}
else if(s[i]=='D'){
if(c[2]){
c[2]--;
}else{
cout<<s[i];
}
}
else if(s[i]=='R'){
if(c[3]){
c[3]--;
}else{
cout<<s[i];
}
}
}
cout<<" "<<ans%p;
cout<<endl;
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
fact[0] = 1;
for(int64_t i = 1; i < N; ++i) fact[i] = (fact[i - 1] * i) % mod;
int t;
cin >> t;
while (t--) {
solve();
}
}
D 小红的差值构造 - easy+hard+extreme
直接贴代码吧
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int n,l;
void solve() {
cin>>n>>l;
if(n>l){
int pos = (n + 1) / 2;
LL x = pos - l / 2, y = pos + (l + 1) / 2;
LL ans = 0;
ans += x*(x-1)/2;
ans += (n-y)*(n-y+1)/2;
LL n1 = (l + 2) / 2, n2 = (l + 1) / 2;
ans += (n1 - 1) * n1 / 2 + (n2 - 1) * n2 / 2;
cout<<x<<" "<<y<<" "<<ans<<endl;
}
else{
LL n1 = (n + 1) / 2, n2 = n / 2;
cout << (n + 1) / 2 << ' ' << (n + 1) / 2 + l << ' ' << (n1 - 1) * n1 / 2 + (1 + n2) * n2 / 2 << '\n';
return;
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
}