#C. 棋盘
- 传统题 1000ms 256MiB
该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。
Description
小J手上有一个n*n的棋盘,他准备放置m个车到棋盘上。
车会攻击与其在同一行或同一列上的所有点。
现在小J想知道,每放当一个车到棋盘上后,有多少个点是不被攻击到的。
Format
Input
第一行两个整数n,m。
接下来m行,每行两个整数x,y表示放置的行和列。
n,m≤10^5
Output
每行输出一个数表示当前不被攻击的位置数目。
Samples
输入数据 1
3 3
1 1
3 1
2 2
输出数据 1
4
2
0
智商题,可通过平移转化。
标记被攻击的行,列,就不用开二维数组了。
#include<bits/stdc++.h>
using namespace std;
long long n,m,ans,x,y;
int ux[100010],uy[100010],tx,ty;
int main()
{
scanf("%lld %lld",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%lld %lld",&x,&y);
if(ux[x]==0)
{
ux[x]++;
tx++;
}
if(uy[y]==0)
{
uy[y]++;
ty++;
}
ans=(n-tx)*(n-ty);
printf("%lld\n",ans);
}
return 0;
}
#D. 珠宝大盗
- 传统题 1000ms 256MiB
该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。
Description
给你N个物品,每个物品都有大小及权值
再给你K个袋子,每个袋子放一个物品
问你最多能拿走的物品的总权值
Format
Input
第一行给出N,K
接下来N行,每行给出一个物品的大小与权值,其均<=1e6
接下来一行,给出K个袋子的大小,其均<=1e8
N,K<=3e5
Output
如题
Samples
输入数据 1
2 1
5 10
100 100
11
输出数据 1
10
输入数据 2
3 2
1 65
5 23
2 99
10
2
输出数据 2
164
a.贪心
#include<bits/stdc++.h>
using namespace std;
long long n,k,ans;
int bsk[300010];
struct t
{
int v,l;
}inf[300010];
bool cmp(t a,t b)
{
return a.v>b.v;
}
int main()
{
scanf("%lld %lld",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d %d",&inf[i].l,&inf[i].v);
for(int i=1;i<=k;i++)
scanf("%d",&bsk[i]);
sort(inf+1,inf+1+n,cmp);
sort(bsk+1,bsk+1+k);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++)
if(bsk[j]>=inf[i].l)
{
ans+=inf[i].v;
bsk[j]=0;
break;
}
}
printf("%lld",ans);
return 0;
}
b.贪心+堆优化
#include<bits/stdc++.h>
using namespace std;
long long ans;
int bsk[300005],n,k,ad=1;
priority_queue<int> q;
struct t
{
int v,l;
}inf[300005];
bool cmp(t a,t b)
{
return a.l<b.l;
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d %d",&inf[i].l,&inf[i].v);
for(int i=1;i<=k;i++)
scanf("%d",&bsk[i]);
sort(bsk+1,bsk+1+k);
sort(inf+1,inf+1+n,cmp);
for(int i=1;i<=k;i++)
{
while(ad!=n+1&&bsk[i]>=inf[ad].l)
{
q.push(inf[ad].v);
ad++;
}
if(q.size()!=0)
{
ans+=q.top();
q.pop();
}
}
printf("%lld",ans);
return 0;
}
c.贪心+set
#include<bits/stdc++.h>
using namespace std;
long long ans;
int n,k,ad=1,num;
priority_queue<int> q;
multiset<int> bsk;
struct t
{
int v,l;
}inf[300005];
bool cmp(t a,t b)
{
return a.l<b.l;
if(a.l==b.l)
return a.v<b.v;
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d %d",&inf[i].l,&inf[i].v);
for(int i=1;i<=k;i++)
{
scanf("%d",&num);
bsk.insert(num);
}
sort(inf+1,inf+1+n,cmp);
for(int i=1;i<=n;i++)
{
auto it=bsk.lower_bound(inf[i].l);
if(it!=bsk.end())
{
bsk.erase(it);
ans+=inf[i].v;
}
}
printf("%lld",ans);
return 0;
}
#E. 相亲大会
- 传统题 1000ms 256MiB
该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。
Description
N个数字按升序排好去参加相亲大会,其权值为1到N 。
如果N是偶数,则均分成两半
如果N是奇数,则前一半为N/2+1个数字,后一半为N/2个数字
就这样不断分下去
当某个区间有3个数字时,则前两个进行匹配,代价为其数字的乘积,第3个数字则派发好人卡,伤心的回家。 如果只有2个数字,则直接进行匹配。
问整个活动办下来,总代价是多少。
Format
Input
第一行给出数字N,N<=2200
Output
如题
Samples
输入数据 1
11
输出数据 1
188
Hint
对于样例
总代价为2+20+56+110=188
1.递归
2.区间[x,y]中,mid=(x+y)/2
如果N是偶数,则mid均分成两半
如果N是奇数,则mid把前一半分为N/2+1个数字,后一半分为N/2个数字
#include<bits/stdc++.h>
using namespace std;
int n;
long long ans;
void fi(int x,int y)
{
int l=y-x+1;
if (x==y)
return ;
if(l==3||l==2)
ans+=x*(x+1);
else
{
int mid=(x+y)/2;
fi(x,mid);
fi(mid+1,y);
}
}
int main()
{
scanf("%d",&n);
fi(1,n);
printf("%lld",ans);
return 0;
}