A题A. Zero Array
思路:每次询问如果是1按照要求修改数组,如果是2则求出让数组变成0数组最少需要的操作数。让数组变成0数组就是统计有多少个不同的数,对于同一个数它的数量则没什么意义,第一个坑是输入的数字可以是0,如果是0的话就不用统计在内。对于每一次1的操作都需要重新统计有多少种不同的数字,如果用数组来存的话一定会超时,所以我们这里用一个map。第二个坑是如果用cincout的话要加上快读,否则会超时。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
map<int,int> mp;
int a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
mp.clear();
long long n,q;
cin>>n>>q;
long long i;
long long res=0;
for(i=1;i<=n;i++)
{
int x;
cin>>x;
a[i]=x;
if(x&&mp[x]==0)
res++;
mp[x]++;
}
while(q--)
{
int m;
cin>>m;
if(m==1)
{
long long p,v;
cin>>p>>v;
long long ans=a[p];
if(v&&mp[v]==0)
res++;
mp[v]++;
a[p]=v;
mp[ans]--;
if(ans&&mp[ans]==0)
{
res--;
}
}
else
{
cout<<res<<endl;
}
}
}
return 0;
}
C题C. Intersections
思路:相交线的对数就是数第一行里每个数右边有多少个数,在第二行里在该数的左边出现,转化为求逆序对数.
未做出的原因:只想到暴力(两层循环),没有想到可以通过逆序对来解决。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],mp[N],c[N];
long long ans;
void _sort(int l,int r)
{
if(l==r)
return ;
int mid=l+r>>1;
_sort(l,mid);
_sort(mid+1,r);
int i=l,j=mid+1,k=l;
while(i<=mid&&j<=r)
{
if(a[i]<=a[j])
c[k++]=a[i++];
else
{
c[k++]=a[j++];
ans += (mid - i + 1);
}
}
while(i<=mid)
{
c[k++]=a[i++];
}
while(j<=r)
{
c[k++]=a[j++];
}
for( i=l;i<=r;i++)
{
a[i]=c[i];
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
mp[x]=i;
}
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
a[i]=mp[x];
}
ans=0;
_sort(1,n);
cout<<ans<<endl;
}
return 0;
}
D题D. Balloons
思路:直接暴力循环如果a[i]>0,就让结果加一
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int mod=1e9+7;
int a[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
int res=0;
for(int i=1;i<=n;i++)
{
if(a[i]>0)
res++;
}
cout<<res<<endl;
}
return 0;
}
F题F. Working Time
思路:为了方便计算,将开始时间与结束时间都装换成分钟制,计算出工作分钟的总数,之后除于60进行比较。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
int res=0;
while(n--)
{
string a,b;
cin>>a>>b;
int sum1=(a[0]-'0')*10+(a[1]-'0');
sum1=sum1*60;
sum1+=(a[3]-'0')*10+(a[4]-'0');
int sum2 = (b[0] - '0') * 10 + (b[1] - '0');
sum2 = sum2 * 60;
sum2 += (b[3] - '0') * 10 + (b[4] - '0');
res+=sum2-sum1;
}
res/=60;
if(res>=m)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
H题H. Cube
思路:给定正方形面积,除于6就变成每个面的面积,之后在开方求出每个边的长度
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int mod=1e9+7;
int a[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int a;
cin>>a;
a=a/6;
cout<<sqrt(a)<<endl;
}
return 0;
}
I题I. Circles
思路:可以推到出来最后的面积公式为d*d/2,但是坑点在于要控制误差,最后保留小数,并且要加上快读模板
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
long long a,b,d;
cin>>a>>b>>d;
double sum=d*d/2.0;
cout<<fixed<<setprecision(7)<<sum<<endl;
}
return 0;
}
J题J. Smallest Difference
思路:要想任意两位数的差值<=1,只能是相邻的前后两位数组成的数组。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int mod=1e9+7;
int a[N],b[N];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(b,0,sizeof(b));
int n;
cin>>n;
int mmax=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(mmax<a[i])
mmax=a[i];
}
for(int i=1;i<=n;i++)
{
b[a[i]]++;
}
int res=0;
for(int i=1;i<mmax;i++)
{
res=max(b[i]+b[i+1],res);
}
cout<<res<<endl;
}
return 0;
}