A. Points in Segments
题意:一个数n和给出一些区间,输出1~n中不在这些区间的数(所有都是闭区间),由于这题数据范围很小,所以暴力就可以解决,如果需要优化,把所有区间按区间左边界从小到大排个序就行
C++代码如下(纯暴力)
#include<iostream>
using namespace std;
const int N=110;
bool st[N];//标记哪些数出现在区间里了
int n,m,sum,ans;
int main(){
cin>>n>>m;
while(n--){
int a,b;
cin>>a>>b;
for(int i=a;i<=b;i++)
if(!st[i])sum++,st[i]=true;
}
cout<<m-sum<<endl;//输出没有出现的数的个数
for(int i=1;i<=m;i++)
if(!st[i])cout<<i<<" ";
cout<<endl;
return 0;
}
B. Obtaining the String
题意:给定两个字符串s和t,问s能不能只通过相邻两个字母之间的交换变成t,如果可以,给出交换的序列ans[],ans[i]表示交换s[ans[i]]和s[ans[i]+1],所以只需要从前往后枚举字符串t,找出t[i]在s中出现的下标j,然后把s[j]从后往前移到下标为i的位置,同时更新序列ans
C++代码如下:
#include<iostream>
#include<vector>
using namespace std;
int main(){
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;//如果已经相等,则不需要任何移动了,continue
int pos=-1;
for(int j=i+1;j<n;j++){
if(s[j]==t[i]){
pos=j;
break;
}
}
if(pos==-1){//如果s[i]在字符串t中不存在,则直接输出-1,跳出循环
cout<<-1<<endl;
return 0;
}
for(int j=pos-1;j>=i;j--){//从后往前把s[pos]移到下标为i的位置上
swap(s[j],s[j+1]);
ans.push_back(j+1);//j+1是因为题目下标从1开始,我们的字符串是从0开始
}
}
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();i++)cout<<ans[i]<<" ";
cout<<endl;
return 0;
}
C. Songs Compression
题意:将n首歌装入内存,n首歌的大小存入数组a[],压缩后的大小存入数组b[],内存为m,问至少压缩多少首歌才可以将所有歌曲存入内存,sum1存储a[]数组的和,sum存储b[]数组的和,先判断sum是否大于m,如果是,则输出-1;否则就将a[i]-b[i]的值存入数组c[i]中,再对c[]进行排序,然后进入循环,从后往前枚举数组c[],每次让sum1减去c[i],直到sum<=m就退出循环
C++代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int c[N];
int n,m;
int main(){
cin>>n>>m;
long long sum=0,sum1=0;
for(int i=1;i<=n;i++){
int a,b;
cin>>a>>b;
sum+=b,sum1+=a;
c[i]=a-b;
}
if(sum>m)cout<<-1<<endl;
else{
sort(c+1,c+n+1);
int cnt=0;
for(int i=n;sum1>m&&i>=1;i--){
sum1-=c[i];
cnt++;
}
cout<<cnt<<endl;
}
return 0;
}
D. Walking Between Houses
题意:一条路边有n个房子(从左到右此次为1,2,...,n),现在要求走k步,所走的距离刚好为s的方案,初始时在1号房子,有两种情况:
1、走k步不可能走过的距离为s,即走最长的路径走k遍都小于s,即(n-1)*k<s
2、走k步距离可以为s,由于房子可以重复经过,所以我们设置一个变量t,t=s/k,就是每一步走t个距离,来回走k步刚好走完了s个距离,当然不是所有的方案都可以整除,所以另外设置一个变量mod,mod=s%k,前mod步我们走t+1个距离,后面的k-mod步走t个距离就可以啦!
C++代码如下:
#include<iostream>
using namespace std;
int main(){
int n;
long long s,k;
cin>>n>>k>>s;
if(k*(n-1)<s)cout<<"NO"<<endl;
else{
//last记录上一次走过的房子
int last=1,flag=1,t=s/k,mod=s%k;
//由于不可能在一个房子呆着,所以每步的距离必须至少为1,若k>s,则不满足要求
if(k>s)cout<<"NO"<<endl;
else{
cout<<"YES"<<endl;
//由于是左右来回走,所以设置flag变量,flag=1表示往右走,flag=-1表示往左走
for(int i=0;i<k;i++){
if(i<mod){
int x=last+flag*(t+1);
cout<<x<<" ";
flag=-flag,last=x;//更新flag和last
}else{
int x=last+flag*t;
cout<<x<<" ";
flag=-flag,last=x;
}
}
cout<<endl;
}
}
return 0;
}
E1. Stars Drawing (Easy Edition)
题意:给出一个图,只有'.'和'*'两个符号,求这些‘*’包含的星星个数,如果包含的星星可以全部覆盖所有的‘*’,则输出星星的个数及它们的信息,否则输出-1,详情见代码,有很详细的注释
C++代码如下:
#include<iostream>
using namespace std;
const int N=110,M=N*N;
char g[N][N];
bool st[N][N];
int n,m,ans,cnt;
//ans记录所有可以被星星覆盖的'*'的数量
struct Node{
//结构体存储能覆盖*的星星的中心和每条边的长度
int u,v,len;
}s[M];
void bfs(int u,int v){
//maxx存储该星星每条边最长的长度,sum存储该星星能覆盖几个新的(即还未被其他星星覆盖的)*符号
int maxx=0,sum=0;
//i枚举的是星星每条边的长度(不包括中心)
//由于不能超过上下左右边界,所以最长为 min(min(u-1,n-u),min(v-1,m-v))
for(int i=1;i<=min(min(u-1,n-u),min(v-1,m-v));i++)
if(g[u+i][v]=='*'&&g[u][v+i]=='*'&&g[u-i][v]=='*'&&g[u][v-i]=='*')//必须上下左右都是*
maxx++;//min是星星每条边的长度
else break;
//如果可以组成星星,则标记u,v号位置已经被计算过了
if(maxx&&!st[u][v])st[u][v]=true,ans++;
for(int i=1;i<=maxx;i++){
//判断!st[][]是为了防止重复计算某个*所在的位置
if(!st[u+i][v])st[u+i][v]=true,ans++,t++;
if(!st[u][v+i])st[u][v+i]=true,ans++,t++;
if(!st[u][v-i])st[u][v-i]=true,ans++,t++;
if(!st[u-i][v])st[u-i][v]=true,ans++,t++;
}
if(t)s[cnt++]={u,v,minn};//如果t不为0,则将该星星存入结构体
}
int main(){
cin>>n>>m;
int sum=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>g[i][j];
if(g[i][j]=='*')sum++;//sum标记星号'*'的个数
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(g[i][j]=='*')
bfs(i,j);
if(sum-ans==0){//如果所有的星号'*'都可以被覆盖,则输出需要的星星数量及它们的信息
cout<<cnt<<endl;
for(int i=0;i<cnt;i++)cout<<s[i].u<<" "<<s[i].v<<" "<<s[i].len<<endl;
}else cout<<-1<<endl;
return 0;
}
E2. Stars Drawing (Hard Edition)
题意:刚开始一看,这不是跟上面一题一模一样吗,仔细一看,数据范围改了,斗胆用上面的代码提交了一下,发现能过,就是有点慢,反正过了就行哈哈哈,N记得开成1010,110是上一题的,所以上一题是有暴力写法吗,不会哇
C++代码见上一题
F. Bracket Substring
不会写T^T,题解也看不懂,几年前的题也搜不到别的题解了......