战绩and总结

又是被兴哥拉一题的一天!!!太牛了ljxyyds!我好菜啊爆哭QAQ
A. Points in Segments
题意:有n条线段和长度m,求在这数轴上从1到m上有哪些不属于任何线段的点
思路①:我敲了发区间合并,调调改改花了十分钟,关于把A题做成难题那种事。。
const int maxn=105;
struct node{
int l,r;
}mo[maxn],m1[maxn];
bool cmp1(node a,node b)
{
return a.l<b.l;
}
int main()
{
int n,m,i,j;
cin>>n>>m;
swap(n,m);
for(i=0;i<m;i++){
cin>>mo[i].l>>mo[i].r;
}
sort(mo,mo+m,cmp1);
int cnt=0,ll,rr;
for(i=0;i<m;i++){
if(i==0){
m1[cnt].l=mo[i].l;
m1[cnt++].r=mo[i].r;
}
else {
if(mo[i].l>m1[cnt-1].r){
m1[cnt].l=mo[i].l;
m1[cnt++].r=mo[i].r;
}
else {
m1[cnt-1].r=max(m1[cnt-1].r,mo[i].r);
}
}
}
map<int ,int >mo;
for(i=0;i<cnt;i++){
for(j=m1[i].l;j<=m1[i].r;j++)
mo[j]++;
}
int ans=0;
for(i=1;i<=n;i++){
if(mo[i]==0) ans++;
}
cout<<ans<<endl;
for(i=1;i<=n;i++){
if(mo[i]==0) cout<<i<<" ";
}
cout<<endl;
return 0;
}
思路②:其实是树状数组的模板但是数据太小了,所以可以暴力,不过可以树状数组跑(线段树也行啦)
`思路③:兴哥的差分数组,比完告诉我用差分我甚至都没回过神了为什么可以用,其实差分数组里面储存相邻的差,存完之后求个额前缀和,在最后查找没有标记的点即可
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m;
int b[200]={0},c[200]={0};
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int L,r;
cin>>L>>r;
b[L]++;b[r+1]--;
}
int res=0;
for(int i=1;i<=m;i++)
{
b[i]+=b[i-1];
if(!b[i])
c[++res]=i;
}
cout<<res<<'\n';
for(int i=1;i<=res;i++)
cout<<c[i]<<" ";
cout<<'\n';
return 0;
}
B. Obtaining the String
题意:
给定两个字符串s1,s2,只能交换s1的相邻元素,为最少需要次可以将s1换成s2.如果没有方法,输出-1.如果有方法,先输出步骤数,然后输出每一次移动的位置。步骤数要在10000以内
思路:两个字符串排序之后要完全相同才有解,有解的情况直接模拟冒泡排序即可,按题意模拟交换
const int maxn=1e5+1000;
int ans[maxn];
int main()
{
map<char ,int >m1,m2;
int n,i,j,cnt=0;
cin>>n;
string s1,s2;
cin>>s1>>s2;
for(i=0;i<s1.length();i++){
m1[s1[i]]++;
}
for(i=0;i<s2.length();i++){
m2[s2[i]]++;
}
bool flag=0;
for(i=0;i<26;i++){
char c1='a'+i;
if(m1[c1]!=m2[c1]) flag=1;
}
if(flag==1){
cout<<-1<<endl;
}
else {
int cnt=0;
for(i=n-1;i>=0;i--){
for(j=0;j<n;j++){
if(s2[i]==s1[j]&&i!=j)
{
while(j!=i&&j<i)
{
ans[cnt++]=j+1;
swap(s1[j],s1[j+1]);
j++;
}
break;
}
}
}
cout<<cnt<<endl;
for(i=0;i<cnt;i++)
cout<<ans[i]<<" ";
}
return 0;
}
C. Songs Compression
题意:手机里有n首歌曲,我有一个u盘,想要把歌全部拷到盘里,我可以对音乐进行压缩,使得原本大小为a【i】的歌曲变为b【i】,求最少压缩多少首歌,才能把歌全部装到盘里
思路:十分明显的贪心题,每次压缩都去选择a【i】和b【i 】差距大的
(不开longlong见祖宗)
#define int long long
const int maxn=1e5+100;
struct node{
int a,b,cha;
}mo[maxn];
bool cmp1(node a,node b)
{
return a.cha>b.cha;
}
signed main()
{
int n,m,i,j;
cin>>n>>m;
int ans=0,m1=0;
for(i=0;i<n;i++)
{
cin>>mo[i].a>>mo[i].b;
mo[i].cha=mo[i].a-mo[i].b;
ans+=mo[i].b; m1+=mo[i].a;
}
sort(mo,mo+n,cmp1);
if(ans<=m)
{
int cnt=0,ff=0;
for(i=0;i<n;i++)
{
if(m1<=m)
{
ff=1;
cout<<cnt<<endl;
break;
}
else
{
m1-=mo[i].a;
m1+=mo[i].b;
cnt++;
}
}
if(ff==0)
cout<<cnt<<endl;
}
else
{
cout<<-1<<endl;
}
}
D. Walking Between Houses
题意:n个房子排成一排,编号从1-n,一开始我在n,我需要移动k次,并且移动的距离刚好是s,输出k次移动到房子的下标
思路:显然每步走s/k格最接近目标,还剩下s%k格,将s%k格分入前面的每一步中
按照兴哥的解释一下为什么最好是走s/k

这样知道走多少格了那么就每次判断当前位置向前走这么多步行不行,不行就向后(longlong见祖宗*2)
#define int long long
signed main()
{
int n,k,s,i,j;
cin>>n>>k>>s;
if(k>s||(n-1)*k<s){
scNO;
}
else
{
scYES;
int d1=s/k;
int d2=s/k+1;
int cnt=s%k;
int m1=1;
for(int i=0;i<k;i++){
if(i<cnt){
if(m1+d2<=n)
cout<<m1+d2<<" ",m1+=d2;
else
cout<<m1-d2<<" ",m1-=d2;
}
else {
if(m1+d1<=n)
cout<<m1+d1<<" ",m1+=d1;
else
cout<<m1-d1<<" ",m1-=d1;
}
}
cout<<endl;
}
return 0;
}
算法竞赛解题策略与实战分析
299

被折叠的 条评论
为什么被折叠?



