头文件如下,代码全部省略头文件
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <algorithm>
#include <queue>
#include <deque>
#include <cstring>
#include <string>
#include <iostream>
#include <set>
#include<sstream>
#define ll long long
#define maxn 101000
#define mod 100000007
#define inf 0x3f3f3f3f
using namespace std;
A题:
题意:给出一个a*b大小的矩阵,位置为(x,y)的格子是坏的,求一个不包含坏格子的最大矩形面积
题解:坏格子会使最大矩形可能有4种情况,分别求出取最大值即可
ac代码:
int did(int x1,int y1,int x2,int y2,int a,int b)
{
if(x1<0||x1>=a||x2<0||x2>=a||y1<0||y1>=b||y2<0||y2>=b)
return 0;
return (abs(x1-x2)+1)*(abs(y1-y2)+1);
}
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int T,a,b,x,y;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&a,&b,&x,&y);
int ans=0;
ans=max(ans,did(0,0,x-1,b-1,a,b));
ans=max(ans,did(0,0,a-1,y-1,a,b));
ans=max(ans,did(x+1,0,a-1,b-1,a,b));
ans=max(ans,did(0,y+1,a-1,b-1,a,b));
printf("%d\n",ans);
}
return 0;
}
B题:
题意:有交通工具A,B,乘坐连续的字符A表示乘坐A可以经过的站点,B同理,第一个和A相互接触的B所在站点可以转车,A同理,乘坐A,B一次分别需要a,b元,乘坐A可以一次性经过所有相邻的A的站点,b同理,一共有p元。给出所有站点,某人从起点出发先走路,后坐车,问此人从起点到终点最少需要走多少路
题解:读完题可以知道,能坐车就坐车,尽量不走路,倒推一下这个人坐车最多能坐多远,剩下的路就是要走的的了
ac代码:
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int t;
scanf("%d",&t);
while(t--)
{
int a,b,p,i;
string s;
scanf("%d%d%d",&a,&b,&p);
cin>>s;
for(i=s.size()-2;i>=0;i--)
{
if(s[i]=='A')
{
if(p<a)break;
p-=a;
}
if(s[i]=='B')
{
if(p<b)break;
p-=b;
}
while(i>0&&s[i]==s[i-1])i--;
}
printf("%d\n",i+2);
}
return 0;
}
C题:
题意:给你一个数字n,n是数组b的元素数目,b[i]=min(a[i2-1],a[i2]),复原出合法的数组a,并且让a的元素排成的串字典序尽量小,a的元素最小是1,最大时2n,如果a复原不出来,输出-1
题解:将b的所有元素都放在a的单数位置上,在双数位置填上对应的尽量小的数,填完之后,如果a[i2]>a[j2]且a[i2-1]<a[j2]且a[i2]>a[j2-1],就交换a[i2]和a[j*2]
ac代码:
int n,a[1000],vis[1000],h[1000];
void solve()
{
memset(h,0,sizeof(h));
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[2*i+1]);
h[a[2*i+1]]=2*i+1;
vis[a[2*i+1]]=1;
}
for(int i=1;i<=2*n;i++)
{
if(h[i]==0){printf("-1\n");return;}
if(!vis[i])continue;
for(int j=i+1;j<=2*n;j++)
{
if(h[j]==0){
a[h[i]+1]=j;
h[j]=h[i]+1;
break;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=2*n;j++)
{
if(a[i*2]>=a[j*2-1]&&a[j*2]>=a[i*2-1]&&a[j*2]<a[i*2])
swap(a[j*2],a[i*2]);
}
}
for(int i=1;i<=2*n;i++)printf("%d ",a[i]);
printf("\n");
}
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int t;
scanf("%d",&t);
while(t--)
{
solve();
}
return 0;
}
D题:
不会做,事后学的
题意:有n种书,每种书有数量为ni,每种书可以花费ti时间增加一本,要让所有种类的书数量各不相同,问最少花费时间多少可以做到
题解:贪心一下,当若干种书的本数相同时,留下花费最多的那个书,不动它,其他种类的书数量全部+1,不断重复即可
ac代码:
multiset<ll>s;
pair<ll,ll>a[201000];
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // lnocal
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)cin>>a[i].first;
for(int i=0;i<n;i++)cin>>a[i].second;
sort(a,a+n);
ll now=-1,sum=0,ans=0;
for(int i=0;i<n;i++)
{
while(s.size()&&now<a[i].first)
{
int big=*s.rbegin();
ans+=sum-big;
sum-=big;
s.erase(s.find(big));
now++;
}
s.insert(a[i].second);
sum+=a[i].second;
now=a[i].first;
}
while(s.size())
{
int big=*s.rbegin();
ans+=sum-big;
sum-=big;
s.erase(s.find(big));
}
printf("%lld",ans);
return 0;
}
E题太难了……孩子不可以,记录下来,以后补TVT