Problem A. 算法竞赛
题意:
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[100005];
signed main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--)
{
memset(a,0,sizeof(a));
int n,m,b,c,d=0;
cin>>n>>m;
while(m--)
{
cin>>b;
a[b]=1;
}
cin>>c;
for(int i=n;i<=c;i++)
{
if(a[i]==0)
d++;
}
cout<<d<<'\n';
}
return 0;
}
Problem C. 市场交易
题意:
思路:
对商品价格和交易次数都从小到大排序,开两个for循环,一个从1-n,一个从n-1,分别从前往后买进,从后往前卖出,把卖出的减去买进的就是最终答案
代码:
#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int N=1e5+20;
struct pi{
int p,num;
};
bool cmp(pi a, pi b)
{
if(a.p==b.p)
return a.num<b.num;
return a.p<b.p;
}
signed main()
{
IOS
int t;
cin>>t;
while(t--)
{
int n,sum=0,ans=0,su=0 ,kkk=0;
cin>>n;
pi a[N];
for(int i=1;i<=n;i++)
{
cin>>a[i].p>>a[i].num;
kkk+=a[i].num;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(a[i].num+sum>kkk/2)
{
ans+=(kkk/2-sum)*a[i].p;
break;
}
ans+=a[i].num*a[i].p;
sum+=a[i].num;
}
sum=0;
for(int i=n;i>=1;i--)
{
if(a[i].num+sum>kkk/2)
{
su+=(kkk/2-sum)*a[i].p;
break;
}
su+=a[i].num*a[i].p;
sum+=a[i].num;
}
cout<<su-ans<<'\n';
}
return 0;
}
Problem D. 新居规划
题意:
思路:
需要特判,错了好几次,因为有几个情况没有考虑到,需要多个特判,把特判加上后就对了,有点麻烦。
代码:
#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
# define f first
# define s second
using namespace std;
pair<int ,int> a[500005];
int bb[500005];
signed main()
{
IOS
int t;
cin>>t;
while(t--)
{
int k=0;
int n,m,sum1=0,sum2=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i].f>>a[i].s;
sum1+=a[i].f;
// if(a[i].f-a[i].s<0)
bb[k++]=a[i].f-a[i].s;
sum2+=a[i].s;
}
if(n==1) cout<<a[1].s<<'\n';
else if(m==n)
{
cout<<sum1<<'\n';
}
else if(n==2)
{
cout<<max(sum1,sum2)<<'\n';
}
else
{ if(m/2==n-1&&m%2!=0) m++;
sort(bb,bb+k);
for(int i=0;i<m-n&&i<k;i++)
{
if(bb[i]>0) break;
sum1-=bb[i];
if(i==n-3&&i<m-n-2)
{
sum1=max(sum1,sum1-bb[i+1]-bb[i+2]);
break;
}
}
cout<<sum1<<'\n';
}
}
return 0;
}
Problem I. 路径规划
题意:
思路:
运用二分,如果值小于mid,就令r=mid-1,否则,令l=mid。
代码:
#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int N=2e6+20;
int a[N];
int n,m;
bool check(int x)
{
int s=-1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[(i-1)*m+j]<=x-1)
{
if(j<s)
return 0;
s=j;
}
}
return 1;
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n*m;i++)
//for(int j=1;j<=m;j++)
cin>>a[i];
int l=0,r=n*m;
while(l<r)
{
int mid=l+r+1>>1;
if(check(mid))
l=mid;
else
r=mid-1;
}
cout<<r<<endl;
}
signed main()
{
IOS
int t;
cin>>t;
while(t--)
solve();
return 0;
}
Problem K. 独立钻石
思路:
用dfs遍历,因为数据范围特别小,所以可以一直遍历,不会时间超限,但如果数据范围大的话就不可以了。
代码:
#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int a[10][10];
int sum,ans;
int n,m,k;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
void dfs()
{
sum=min(sum,ans);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j])
{
for(int t=0;t<=3;t++)
{
int tx=dx[t]+i;
int ty=dy[t]+j;
if(a[tx][ty])
{
int xx=tx+dx[t],yy=ty+dy[t];
if(xx>=1&&yy>=1&&xx<=n&&yy<=m&&a[xx][yy]==0)
{
a[tx][ty]=0;
a[i][j]=0;
a[xx][yy]=1;
ans--;
dfs();
ans++;
a[i][j]=1;
a[tx][ty]=1;
a[xx][yy]=0;
}
}
}
}
}
}
}
void solve()
{
memset(a,0,sizeof(a));
int x,y;
cin>>n>>m>>k;
sum=k,ans=k;
for(int i=1;i<=k;i++)
{
cin>>x>>y;
a[x][y]=1;
}
dfs();
cout<<sum<<endl;
return;
}
signed main()
{
IOS
int t;
cin>>t;
while(t--)
{
solve();
}
return 0;
}