今天?准确的说是昨天,算咕了吧,晚上和队友商量题目,下午比赛,上午时间不够补题,碰上这次EF让我非常头大,时间确实不够,E已经完全理解了,注释添加完毕,F不行,完全看不懂,没有头绪,直接贴标程代码了,留给大佬们自己品。
A C都很水,B题我自己看到的时候,感觉是直接找到一个字母不同就直接暴力找位置交换,然后看了眼答案,正解,我自己还想着先开个桶记录一下各个字母的个数,结果标程直接交换过程中判断,给我教育了一番,可,所以这个代码贴标程。D题,我的思路就是贪心分配每次的步长就好,尽可能短即可,但是特判NO的时候分情况搞得我头大,WA了两发。
E1,E2,这种题目第一次见,完全没思路,看题时就被吓死了,看了题解还是看不懂,慢慢啃了一个多小时,发现思路其实不是很难想,代码不太好理解,注释加上了。
F超出我的理解范围了···现在还是不懂,先贴上,留个坑····
A
#include <iostream>
using namespace std;
int a[105];
int main()
{
int n,m; cin>>m>>n;
for(int i=0;i<m;i++){
int x,y; cin>>x>>y;
for(int j=x;j<=y;j++)
a[j]=1;
}
int res=0;
for(int i=1;i<=n;i++){
if(!a[i]) res++;
}
cout<<res<<endl;
for(int i=1;i<=n;i++){
if(!a[i]) cout<<i<<" ";
}
return 0;
}
B
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int n;
string s, t;
cin >> n >> s >> t;
vector<int> ans;
for (int i = 0; i < n; ++i) {
if (s[i] == t[i]) continue;
int pos = -1;//这个操作可以说是非常秀了 我只会开个桶记录字母个数 丢人
for (int j = i + 1; j < n; ++j) {
if (s[j] == t[i]) {
pos = j;
break;
}
}
if (pos == -1) {//
cout << -1 << endl;
return 0;
}
for (int j = pos - 1; j >= i; --j) {
swap(s[j], s[j + 1]);
ans.push_back(j);
}
}
//assert(s == t);
cout << ans.size() << endl;
for (auto it : ans) cout << it + 1 << " ";
cout << endl;
return 0;
}
C
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+10;
typedef long long LL;
int a[N],b[N];
int main()
{
int n,m; cin>>n>>m;
LL sum=0;
for(int i=0;i<n;i++){
cin>>a[i]>>b[i];
sum+=b[i];
a[i]=a[i]-b[i];
}
if(m<sum){cout<<-1<<endl; return 0;}
m-=sum;
sort(a,a+n);
int res=n,index=0;
while(m>=a[index]&&res){
m-=a[index];
index++;
res--;
}
cout<<res<<endl;
return 0;
}
D
#include <iostream>
using namespace std;
typedef long long LL;
int main()
{
LL n,k,m; cin>>n>>k>>m;
LL ave=m/k;
LL cnt=m%k;
if((cnt && n<ave+2)||(cnt==0 && n<ave+1 )||k>m ){cout<<"NO"<<endl; return 0; }
cout<<"YES"<<endl;
int now=1;
for(int i=1;i<=cnt;i++){
if(i&1)
now=now+ave+1;
else
now=now-ave-1;
cout<<now<<" ";
}
for(int i=cnt+1;i<=k;i++){
if(i&1)
now=now+ave;
else
now=now-ave;
cout<<now<<" ";
}
return 0;
}
E1
#include <bits/stdc++.h>
using namespace std;
#define forn(i, n) for (int i = 0; i < int(n); i++)
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};
const int N = 1001;
int n, m;
vector<string> f;//存原图
int d[N][N][4];//
int r[N][N], a[N][N], b[N][N];//r存(x,y)的星图的size a[x][y]存(x,y)的*被覆盖后 当前点与所在的星图最靠右的点 点的个数
//b[x][y]存(x,y)的*被覆盖后 当前点到所在的星图最靠下的点 点的个数
int getd(int i, int j, int k) {//i j是坐标 k是方向 得到从i j出发,k方向上*的个数
int dxk = dx[k];
int dyk = dy[k];
int result = 0;
while (i >= 0 && i < n && j >= 0 && j < m && f[i][j] == '*')
result++, i += dxk, j += dyk;
return result;
}
int main() {
cin >> n >> m;
f = vector<string>(n);
forn(i, n)//读入图
cin >> f[i];
memset(d, -1, sizeof(d));
int result = 0;//一共用了多少个
for (int i = 1; i + 1 < n; i++)
for (int j = 1; j + 1 < m; j++)//开始枚举
if (f[i][j] == '*') {
bool around = true;
forn(k, 4)//around判断四个方向是不是都有*
around = around && (f[i + dx[k]][j + dy[k]] == '*');
if (around) {//如果四个方向都有*
r[i][j] = INT_MAX;//存储该点添加的星图的size
forn(k, 4)//找到四个方向里 星size最短的
r[i][j] = min(r[i][j], getd(i, j, k) - 1);
result++;
//[i][j-r[i][j]]本次更新后,第i行中第一个被更新的*的位置 存储的值是本次更新后最后一个被更新的*的位置
a[i][j - r[i][j]] = max(a[i][j - r[i][j]], 2 * r[i][j] + 1);
b[i - r[i][j]][j] = max(b[i - r[i][j]][j], 2 * r[i][j] + 1);
}
}
vector<string> g(n, string(m, '.'));//相当于本题中的空图
forn(i, n) {//按行添加*
int v = 0;
forn(j, m) {//v将点的个数转化成距离并存储下来
v = max(v - 1, a[i][j]);
if (v > 0)
g[i][j] = '*';
}
}
forn(j, m) {//按列添加*
int v = 0;
forn(i, n) {
v = max(v - 1, b[i][j]);
if (v > 0)
g[i][j] = '*';
}
}
if (f == g) {
cout << result << endl;
forn(i, n)
forn(j, m)
if (r[i][j] > 0)
cout << i + 1 << " " << j + 1 << " " << r[i][j] << endl;
} else
cout << -1 << endl;
}
E2
#include <bits/stdc++.h>
using namespace std;
/*
整体思路跟暴力类似
区别在于 不是一遍遍历 一边更新四个方向的长度
而是预处理 分别用u d l r四个vector进行存储
*/
int n, m;
vector<string> s;
vector<string> draw(const vector<pair<pair<int, int>, int>> &r) {//这个过程挺骚气的·· 真的NB
vector<string> f(n, string(m, '.'));// f 初始化一个n行m列 全为 . 的图
vector<vector<int>> h(n, vector<int>(m));//每一行都是一个大小为m的vector
vector<vector<int>> v(n, vector<int>(m));
// cout<<"shucu"<<endl;
// for(auto it:r){
// cout<<it.second<<" ";
// if(it.first.first==m-1)
// cout<<endl;
// }
// cout<<endl<<"end"<<endl;
for (auto it : r) {
int x = it.first.first;
int y = it.first.second;
int len = it.second;
++v[x - len][y];//起点为1
if (x + len + 1 < n)
--v[x + len + 1][y];//终点为-1
++h[x][y - len];
if (y + len + 1 < m)
--h[x][y + len + 1];
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (i > 0) v[i][j] += v[i - 1][j];
if (j > 0) h[i][j] += h[i][j - 1];
if (v[i][j] > 0 || h[i][j] > 0)
f[i][j] = '*';
//cout<<v[i][j]<<" ";
}
//cout<<endl;
}
//cout<<"eend"<<endl;
return f;
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
cin >> n >> m;
s = vector<string>(n);//存图
for (int i = 0; i < n; ++i) {
cin >> s[i];
}
vector<vector<int>> l(n, vector<int>(m));
vector<vector<int>> r(n, vector<int>(m));
vector<vector<int>> u(n, vector<int>(m));
vector<vector<int>> d(n, vector<int>(m));//分别记录当前位置四个方向上 * 的长度
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (i > 0) {
if (s[i][j] != '.')
u[i][j] = u[i - 1][j] + 1;
} else {
u[i][j] = s[i][j] != '.';
}
if (j > 0) {
if (s[i][j] != '.')
l[i][j] = l[i][j - 1] + 1;
} else {
l[i][j] = s[i][j] != '.';
}
}
}
for (int i = n - 1; i >= 0; --i) {
for (int j = m - 1; j >= 0; --j) {
if (i < n - 1) {
if (s[i][j] != '.')
d[i][j] = d[i + 1][j] + 1;
} else {
d[i][j] = s[i][j] != '.';
}
if (j < m - 1) {
if (s[i][j] != '.')
r[i][j] = r[i][j + 1] + 1;
} else {
r[i][j] = s[i][j] != '.';
}
}
}//四个方向预处理完毕
//更新每个位置的星图size
vector<pair<pair<int, int>, int> > ans;//三维数组 前两维是坐标 第三维是星图的size
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (s[i][j] == '*') {
int len = min(min(u[i][j], l[i][j]), min(d[i][j], r[i][j])) - 1;
if (len != 0) {
ans.push_back(make_pair(make_pair(i, j), len));
}
}
}
}
if (draw(ans) != s) {//根据自己的答案 画出来 跟原图比较
cout << -1 << endl;
} else {
cout << ans.size() << endl;
for (auto it : ans) {
cout << it.first.first + 1 << " " << it.first.second + 1 << " " << it.second << endl;
}
}
return 0;
}
F
#include <bits/stdc++.h>
using namespace std;
const int N = 203;
const int MOD = 1e9 + 7;
int n, ssz;
string s;
int len[N][2];
int dp[N][N][N][2];
int calc(const string &t) {
int tsz = t.size();
for (int i = tsz; i > 0; --i) {
if (s.substr(0, i) == t.substr(tsz - i, i))
return i;
}
return 0;
}
void add(int &a, int b) {
a += b;
if (a >= MOD)
a -= MOD;
if (a < 0)
a += MOD;
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
cin >> n >> s;
ssz = s.size();
if (s[0] == '(')
len[0][0] = 1;
else
len[0][1] = 1;
string pref;
for (int i = 0; i < ssz; ++i) {
pref += s[i];
pref += '(';
len[i + 1][0] = calc(pref);
pref.pop_back();
pref += ')';
len[i + 1][1] = calc(pref);
pref.pop_back();
}
dp[0][0][0][0] = 1;
for (int i = 0; i < 2 * n; ++i) {
for (int j = 0; j <= n; ++j) {
for (int pos = 0; pos <= ssz; ++pos) {
for (int f = 0; f < 2; ++f) {
if (dp[i][j][pos][f] == 0) continue;
if (j + 1 <= n)
add(dp[i + 1][j + 1][len[pos][0]][f | (len[pos][0] == ssz)], dp[i][j][pos][f]);
if (j > 0)
add(dp[i + 1][j - 1][len[pos][1]][f | (len[pos][1] == ssz)], dp[i][j][pos][f]);
}
}
}
}
int ans = 0;
for (int i = 0; i <= ssz; ++i)
add(ans, dp[2 * n][0][i][1]);
cout << ans << endl;
return 0;
}