A.Points in Segments
题目大意:
给你n个小区间和最大边界m,这n个区间分布在1-m的大数轴区间上,请你输出这个数轴上不属于任何小区间的数的数目和本身。
解题思路:
将输入的区间遍历对区间内的数字进行唯一标记并统计数量sum,则未在任何小区间的数字数目就是m-sum,最后遍历大区间,未被标记的就是不在任何小区间的数了。
代码如下:
#include<iostream>
using namespace std;
int book[110];
int main()
{
int n,m,sum=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int a,b;
cin>>a>>b;
for(int i=a;i<=b;i++)
{
if(book[i]==0)sum++;
book[i]=1;
}
}
cout<<m-sum<<endl;
for(int i=1;i<=m;i++)
{
if(book[i]==0)cout<<i<<' ';
}
cout<<endl;
return 0;
}
B. Obtaining the String
题目大意:
给定两个字符串s和t,问s能否通过有限次(10^4)相邻元素交换位置得到字符串t。如果能,输出交换次数和每次交换中交换对象前者的编号,否则输出-1。
解题思路:
首先用标记数组判断两个字符串组成元素种类和数量是否相同。不相同则输出-1,否则就开始移动。首先遍历字符串s,找到不相同的地方后从这个地方出发找本应该放在这里的字符在s中所在的位置,然后逐渐进行相邻元素交换直到对于元素归位,并保存交换前者编号和统计交换次数。
代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int main()
{
string s,t;
int n,a[26]={0},b[26]={0};
int sum=0,result[10010]={0},k=0,cur=0,count=0;
cin>>n;
cin>>s>>t;
for(int i=0;i<n;i++)//两个字符串包含字符书数量和种类是否相同
{
int k1=s[i]-'a',k2=t[i]-'a';
a[k1]++;b[k2]++;
}
int flag=true;
for(int i=0;i<26;i++)
{
if(a[i]!=b[i])
{
flag=false;
break;
}
}
if(!flag)cout<<-1<<endl;//不相同
else if(s==t)cout<<0<<endl;//两串相等
else
{
for(int i=0;i<n;i++)//遍历
{
if(s[i]==t[i])continue;//相同直接跳过
for(int j=i+1;j<n;j++)//找t[i]在s中的对应位置并移动
{
if(s[j]==t[i])
{
k=j;//记录位置
break;
}
}
while(s[i]!=t[i])//移动
{
count++;//统计移动次数
if(count>1e+4)
{
cout<<-1<<endl;
return 0;
}
result[cur++]=k;//保存移动编号,记录路径
swap(s[k],s[k-1]);//交换
k--;
}
}
cout<<cur<<endl;
for(int i=0;i<cur;i++)cout<<result[i]<<' ';
}
}
C.Songs Compression
题目大意:
有n首歌,每一首歌本身占据内存为a,可以压缩至b,现在给一个总内存m,问是否可以将所有的歌都保存下来,是的话最少压缩多少首歌?否就输出-1。
解题思路:
贪心,按照每首歌压缩空间从大到小排个序,先压缩大的。需要注意的存在不需要压缩也可以的情况,最少数就是0,这里没注意吃了一个WA。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct songs
{
long long len1,len2,len3;
}s[100010];
int cmp(songs a,songs b)
{
return a.len3>b.len3;
}
int main()
{
long long n,m,sum1=0,sum2=0;
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>s[i].len1>>s[i].len2;
sum1+=s[i].len2;sum2+=s[i].len1;
s[i].len3=s[i].len1-s[i].len2;
}
if(sum1>m) cout<<-1<<endl;
else if(sum1==m)cout<<n<<endl;
else
{
sort(s,s+n,cmp);
long long sum3=0,i=0;
while(sum2>m)
{
sum2-=s[i].len3;
sum3++;
i++;
}
cout<<sum3<<endl;
}
return 0;
}
D.Walking Between Houses
题目大意:
有n个线性分布的房子,初始时刻站在1号房子,要求是否能在移动k步时移动距离达到s,是则输出YES和路径,即访问过的房子编号(可来回访问,不能原地不动),否则输出NO。
解题思路:
这个题自己没写出来,一开始想了大爆搜,DP感觉都不行。后来补题时候发现有一些贪心思想,这个题难处在于方法很多,同一种情况对于很多种答案,我这里相当于是一个模拟吧,维护一个当前所在房子编号的变量,计算当前步下移动的距离,如果当前剩余距离大于n-1,那一步就走n-1,否则先走n-k(k是剩下的步数)然后每步只移动1格,总结起来就是move=min(s-k,n-1);
代码如下:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long n,k,s;
cin>>n>>k>>s;
if(k>s||k*(n-1)<s)cout<<"NO"<<endl;//
else
{
cout<<"YES"<<endl;
long long house=1;
while(k--)
{
long long move=min(s-k,n-1);
s-=move;
if(house+move>n){house-=move;cout<<house<<' ';}
else{house+=move;cout<<house<<' ';}
}
}
return 0;
}
E1.Stars Drawing (Easy Edition)
题目大意:
给定一个图,能否用题目中规定的不同型的星图(size 1,size 2……)做出这个图,关注重点是*
号,.
可忽略。如果可以,输出该型星图中心星所在位置以及这个图的大小(也就是size),否则输出-1。注意必须将样例中的每一个*
都能画出来。
解题思路:
我只会模拟的写法,需要注意标记每一个星图在样例中所占据的星,还要注意全是.
的情况,代码如下:
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
char grid[110][110];//储存样例
int book[110][110];//标记*
struct result
{
int row,colume,central;//行列,中心
}a[11000];
int main()
{
int row,colume;
cin>>row>>colume;
for(int i=1;i<=row;i++)
{
for(int j=1;j<=colume;j++)
cin>>grid[i][j];
}
int count=0,flag1=0;
for(int i=2;i<=row-1;i++)
{
for(int j=2;j<=colume-1;j++)
{
if(grid[i][j]=='*')
{
flag1=1;//对于全是.情况的特判
int top=0,bottom=0,l=0,r=0;
int k1=i,k2=i,k3=j,k4=j;//开始找以当前为中心的星图大小
while(grid[i][++k3]=='*')top++;
while(grid[i][--k4]=='*')bottom++;
while(grid[++k1][j]=='*')r++;
while(grid[--k2][j]=='*')l++;
int p=min(min(top,bottom),min(r,l));//星图size
int t1=i,t2=i,t3=j,t4=j;
if(p)//开始标记
{
book[i][j]=1;
int t1=i,t2=i,t3=j,t4=j;
while(t3<j+p)book[i][++t3]=1;
while(t4>j-p)book[i][--t4]=1;
while(t2>i-p)book[--t2][j]=1;
while(t1<i+p)book[++t1][j]=1;
count++;
a[count].row=i;a[count].colume=j;a[count].central=p;//记录这个图
}
}
}
}
bool flag=true;
for(int i=1;i<=row;i++)
{
for(int j=1;j<=colume;j++)
{
if(grid[i][j]=='*')
{
if(book[i][j]==0)//有存在未被占据的*,则无法画出
{
i=row;
flag=false;
break;
}
}
}
}
if(!flag1)cout<<0<<endl;//全是.
else if(count&&flag)
{
cout<<count<<endl;
for(int i=1;i<=count;i++)cout<<a[i].row<<' '<<a[i].colume<<' '<<a[i].central<<endl;
}
else cout<<-1<<endl;
}