A题:大水题,直接对暴力对区间点打标记,最后扫一遍没有打标记的点记录就行了。
代码略。
B题:也是比较水,因为是任意小于1e4的操作数都行,而字符串最长只有50.所以从后开始直接对比每个位置的字符是否相等,如果不相等,就向前找第一相等的,然后把他移动到这个位置,如果找不到就是-1.
#include<bits/stdc++.h>
using namespace std;
char s[110],t[110];
int N;
void solve(){
vector<int> res;
for(int i=N;i>=1;--i){
if(s[i] == t[i])
continue;
else{
bool isfind = false;
int pos;
for(pos=i-1;pos>=1;--pos){
if(s[pos] == t[i]){
isfind = true;
break;
}
}
if(!isfind) break;
while(pos < i){
swap(s[pos],s[pos+1]);
res.push_back(pos);
pos++;
}
}
}
if(strcmp(s+1,t+1) == 0){
cout << res.size() << endl;
for(int i=0;i<res.size();++i){
cout << res[i];
if(i != res.size()-1)
cout << " ";
else
cout << endl;
}
}
else{
cout << -1 << endl;
}
}
int main(void){
cin >> N;
cin >> (s+1) >> (t+1);
solve();
return 0;
}
C题:水题,直接求出当前的未压缩前的总和,和压缩后的总和,先比较一下判断是否能放入硬盘,然后再按照(压缩前大小-压缩后大小)即能减少的大小排序就行了。然后开始枚举直到未压缩前总和-减小的大小<=硬盘大小即可。
代码略
D题:需要思考一下。判断bas = S%K 的结果,如果是0,那么每步增加bas就可以,即1,bas+1,来回跑就可以。如果不是0,那么记录leave = S%K,前leave步是增加bas+1,后面依然是增加bas即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll N,K,S;
int main(void){
cin >> N >> K >> S;
if((N-1)*K < S || S < K){
cout << "NO" << endl;
}
else{
vector<int> res;
if(S % K == 0){
ll Bas = S/K;
for(int i=1;i<=K;++i){
if(i&1)
res.push_back(Bas+1);
else
res.push_back(1);
}
}
else{
ll Bas = S/K;
ll leave = S%K;
ll Now = 1,add = Bas;
for(int i=1;i<=K;++i){
if(i <= leave){
if(i&1)
Now = Now + add+1;
else
Now = Now - (add+1);
}
else{
if(i&1)
Now = Now + add;
else
Now = Now - add;
}
res.push_back(Now);
}
}
cout << "YES" << endl;
for(int i=0;i<res.size();++i){
cout << res[i];
if(i != res.size()-1)
cout << " ";
else
cout << endl;
}
}
return 0;
}
E1,E2:两个题目一样只是范围不同。所以直接按照最大来讲。直接求出每个’*’位置的L,R,U,D相邻的最远的’*’的位置,扫描一遍地图就可以。然后再再求出该点到,L,R,U,D的距离,如果大于0,那么该点就是一个星星。把该星星的所有左边全部标记上。
最后如果存在’*’没有被标记,那么就输出-1,否则就输出所有星星。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1010;
class Node{
public:
int l,r,u,d;
};
Node q[MAX][MAX];
class v{
public:
int x,y,s;
v();
v(int _x,int _y,int _s);
};
char str[MAX][MAX];
bool book[MAX][MAX];//标记'*'的所有坐标
int N,M;
//处理出每个点位置L,R,U,D,相邻的最远的'*'
void init(){
for(int i=1;i<=N;++i){
int pos = 0;
for(int j=1;j<=M;++j){
if(str[i][j] == '*'){
q[i][j].l = pos+1;
}
else{
pos=j;
}
}
pos = M+1;
for(int j=M;j>=1;--j){
if(str[i][j] == '*'){
q[i][j].r = pos-1;
}
else{
pos=j;
}
}
}
for(int i=1;i<=M;++i){
int pos = 0;
for(int j=1;j<=N;++j){
if(str[j][i] == '*'){
q[j][i].u = pos+1;
}
else{
pos = j;
}
}
pos = N+1;
for(int j=N;j>=1;--j){
if(str[j][i] == '*'){
q[j][i].d = pos-1;
}
else{
pos = j;
}
}
}
}
void show(int i,int j){
cout << q[i][j].l << " " << q[i][j].r << " " << q[i][j].u << " " << q[i][j].d << endl;
}
void solve(){
init();
memset(book,false,sizeof(book));
vector<v> vec;
for(int i=1;i<=N;++i){
for(int j=1;j<=M;++j){
if(str[i][j] == '*'){
int s = min(min(j-q[i][j].l,q[i][j].r-j),min(i-q[i][j].u,q[i][j].d-i));
if(s != 0){
vec.push_back(v(i,j,s));
for(int k=0;k<=s;++k){
book[i][j+k] = true;
book[i+k][j] = true;
book[i-k][j] = true;
book[i][j-k] = true;
}
}
}
}
}
bool isok = true;
for(int i=1;i<=N;++i){
for(int j=1;j<=M;++j){
if(str[i][j] == '*' && !book[i][j]){
isok = false;
break;
}
}
}
if(!isok){
printf("-1\n");
}
else{
int Size = vec.size();
printf("%d\n",Size);
for(vector<v>::iterator it = vec.begin();it != vec.end();++it){
printf("%d %d %d\n",it->x,it->y,it->s);
}
}
}
int main(void){
scanf("%d%d",&N,&M);
for(int i=1;i<=N;++i){
scanf("%s",str[i]+1);
}
solve();
return 0;
}
v::v(){
x = y = s = 0;
}
v::v(int _x,int _y,int _s){
x = _x;
y = _y;
s = _s;
}