这次题目出的都是一些偏向于基础的题目,就是一些简单的模拟,思维,以及基础算法(二分,前缀和)
(点击题目标题,进入原题)
我是签到题
题解:就是说给你 t 组数据,然后每组数据输入两个,一个x,一个y,然后先输出其中的最小值,再输出其中的最大值。
#include<bits/stdc++.h>
using namespace std; long long x,y;
int main()
{long long t;cin>>t;while(t--){cin>>x>>y;printf("%lld %lld\n",min(x,y),max(x,y));}return 0;
}
能否形成不同的矩形
题解:能够拆开并且拼凑到一起的边一定是偶数,因此,我们就是单纯去模拟就可以了,如果是偶数就去分开,将其拼凑在一起,判断和之前的是否形成了不一样的矩形(纯粹的模拟题,题目上咋说,你去就咋做)
#include<bits/stdc++.h>
using namespace std;
#define int long longint t;
int a,b;
signed main()
{ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>t;while(t--){int flag=0;cin>>a>>b;int x=0,y=0;if(a%2==0){y=2*b;x=a/2;if(x!=a&&y!=b&&x!=b&&y!=a){flag=1;}}if(b%2==0){y=b/2;x=2*a;if(x!=a&&y!=b&&x!=b&&y!=a){flag=1;}}if(flag==1){cout<<"YES\n";}else{cout<<"NO\n";}}return 0;
}
能否形成不同的字符串
题解:这题比第二个还简单,只需要判断是否能够形成不同的字符串,首先就是你得先判断字符串里面是否有不同的字母,如果没有肯定 是NO,如果有不同的字母,输出YES,并且随机交换两个不同的字母输出就行
#include<bits/stdc++.h>
using namespace std;
string s;
int t;
int flag;
char r[5000005];
int x,y;
int main()
{cin>>t;while(t--){flag=0;cin>>s;int len=s.size();for(int i=1;i<len;i++){if(s[i]!=s[i-1]){flag=1;x=i,y=i-1;}}for(int i=1;i<len;i++){r[i-1]=s[i];}r[len-1]=s[0];if(flag==0)printf("NO\n");else{printf("YES\n");for(int i=0;i<len;i++){printf("%c",r[i]);}printf("\n");}}return 0;
}
查找
这题唯一考点就是二分查找,并且数据结构课应该讲过(我不怎么听课,我不确定,应该是讲过的)
#include<bits/stdc++.h>
using namespace std;int n,m;
int a[1000005];
int target,l,r,mid;
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=1;i<=m;i++){scanf("%d",&target);l=1;r=n;while(l<r){mid=(l+r)/2;if(a[mid]>=target)r=mid;elsel=mid+1;}if(a[l]==target)printf("%d ",l);elseprintf("-1 ");}return 0;
}
A. Contest Proposal
这题就是说有n个题目,每个题目的难度为a[i],要求每个题目的难度不大于对应的b[i],每次可以添加一个题目并且删去最难的题目,求最多能添加几个题目
思路很简单,只要a[i]>b[i],那么就将a[i]改成b[i],并且重新对数组进行排序,然后继续比较就行
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll t;
ll n;
ll a[105];
ll b[105];
void solve(){ll u = n;ll sum = 0;for(int i=n;i>=1;i--){if(a[i]>b[u]){sum++;}else {u--;}}printf("%lld\n",sum);
}
int main()
{cin>>t;while (t--) {cin>>n;for (int i = 1; i <= n; i++)cin>>a[i];for (int i = 1; i <= n; i++)cin>>b[i];solve();}return 0;
}
B. Sasha and the Drawing
题解:纯思维性题目,做不出来也算正常,这题 自己在本子上画的话,会发现最多只有前n - 1给才能占两个对角线,也就是2*(n-1)个对角线,剩下的一个涂色只能占一个对角线,因此我们通过这个思路去计算即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;signed main()
{cin>>t;while(t--){cin>>n>>k;int sum=2*n-2;if(k<=(2*n-2)*2){if(k%2==0)cout<<k/2<<"\n";elsecout<<k/2+1<<"\n";}else{int cnt=2*n-2;k-=(2*n-2)*2;cnt+=k;cout<<cnt<<"\n";}}return 0;
}
P1314 [NOIP2011 提高组] 聪明的质监员
题意:就是说给你n个矿石,然后,这n个矿石都有自己的重量w,以及其价值v,我们有一种判断机制,就是说给你m个区间范围,每次给你一个左边界L和右边界R,我们的计算机理是,这个区间内的大于规定筛选重量W的数量,乘以大于筛选重量的价值,然后将总的算出来的y累加到一起,看看和规定的标准值S最小差多少,输出最小的参数W
思路,我们发现这题数据超大,必然会有优化方法,我们通过上面·的题意可以发现,我们的参数设置的越大,能过筛选的石头越少,得到的y值越小,设置的越小,能筛选过的石头越多,得到的y值越大,因此我们可以用二分(二分的范围就是给的数据的石头的最小值到最大值,但是我们还要扩增范围,最小值减一,最大值加二)然后我们每次二分的就是参数W,然后在计算过程中要用到前缀和优化,我们要去记录出现的大于参数的矿石数目以及总价值,然后我们去计算总的Y值,Y值大于标准值S就说明,我们的参数设置的小了,要增大左边界,要是小于标准值,就说明,我们的参数设置的太大了,要缩小右边界
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,s;
int w[200005];
int v[200005];
int l[200005],r[200005];
int maxn=0;
int minn=0x3f3f3f3f3f3f3f3f;
int sumn[200005];
int sumv[200005];
int ans=0;//统计本次筛选的总价值
int mn=0x3f3f3f3f3f3f3f3f;//统计最小差值
bool check(int mid)
{memset(sumn,0,sizeof(sumn));memset(sumv,0,sizeof(sumv));int ans=0;//统计总的价值也就是y[i] for(int i=1;i<=n;i++){if(w[i]>=mid){sumn[i]=sumn[i-1]+1;//统计能过筛查的数量sumv[i]=sumv[i-1]+v[i];//统计能过筛查的价值 }else{sumn[i]=sumn[i-1];sumv[i]=sumv[i-1];}}for(int i=1;i<=m;i++){ans+=(sumn[r[i]]-sumn[l[i]-1])*(sumv[r[i]]-sumv[l[i]-1]);}mn=min(mn,llabs(ans-s));if(ans>s)return true;return false;
}
signed main()
{cin>>n>>m>>s;for(int i=1;i<=n;i++){cin>>w[i]>>v[i];maxn=max(maxn,w[i]);//二分的上下边界 minn=min(minn,w[i]);}int left,right,mid;for(int i=1;i<=m;i++){cin>>l[i]>>r[i];}left=minn-1,right=maxn+2;while(left<=right){mid=(left+right)/2;if(check(mid)){left=mid+1;}else{right=mid-1;}}cout<<mn;return 0;
}