目录
A
B
C
D
E
https://codeforces.com/contest/1472/problem/A
思路:一张纸横向及纵向所能剪切的数量是固定的,相乘即可。
#include
#include
#define ll long long
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
ll w,h,n;
scanf("%lld%lld%lld",&w,&h,&n);
int ww=0,hh=0;
while(w % 2 == 0){ww++;w/=2;}
while(h % 2 == 0){hh++;h/=2;}
ww = pow(2,ww);
hh = pow(2,hh);
ll maxn = ww*hh;
if(maxn>=n)
cout<<"YES"<
https://codeforces.com/contest/1472/problem/B
思路:若所有糖的重量的总和为奇数,则无论如何,都不可能整分。若总数为偶数,则需判断其除二后结果是奇数还是偶数。
若该结果为偶数,则定可以分。若该结果为奇数,每两个1在一起可以等价于一个2,而奇数的构成是 一堆偶数,加一个1 即可,因此,只要给的数字中有1的出现次数大于等于2即可实现奇数分法的构造。
#include
#include
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
scanf("%d",&n);
int s1=0,s2=0,sum=0;
for(int i=1;i<=n;i++)
{
int t;
scanf("%d",&t);
if(t == 1) s1++;
if(t == 2) s2++;
}
sum = s1+2*s2;
if(sum % 2 == 1)
{
cout<<"NO"<=2)
{
cout<<"YES"<
https://codeforces.com/contest/1472/problem/C
思路:理解题意后 模拟去跑整个过程,记录最大值即可。不过要注意优化! 逆序去进行遍历(类似于记忆化的方式,将从该点至最后跳出所得答案 存储与ta数组对应索引中,前面的点跳到它身上直接读值即可,以次优化时间复杂度)
#include
#include
#define ll long long
using namespace std;
ll a[200005],ta[200005];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
ll mmax = -1;
for(int i=n;i>=1;i--)
{
ll tans=0;
int crs=i;
tans+=a[crs];
if(crs+a[crs]<=n)
tans += ta[crs+a[crs]];
ta[crs] = tans;
mmax = max(mmax,tans);
}
cout<
https://codeforces.com/contest/1472/problem/D
思路:博弈论,贪心思想,确保每一步都为当前对自己的最优选择。先进行排序,显然要从最大的开始拿。当到你的回合时,你可以选择去选取使自己加分的数,或选取对方的此时最大的数(when 对方选取该数后 会比 当前自己选择自己的数 对自己更不利 即:对方此时最大的数,要大于自己此时最大的数时,去选择对方此时最大的数)。ps.宁可自己不加分,也不能让别人加更多的分。。太贪了orz
#include
#include
#include
#define ll long long
#define N 200005
using namespace std;
ll ev[N],od[N];
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
scanf("%d",&n);
int evn=0,odn=0;
for(int i=1;i<=n;i++)
{
ll t;
scanf("%lld",&t);
if(t % 2 == 0)
{
evn++;
ev[evn]=t;
}
else
{
odn++;
od[odn]=t;
}
}
sort(ev+1,ev+evn+1);
sort(od+1,od+odn+1);
ll aans=0,bans=0;
int evc=evn,odc=odn;
for(int i=1;i<=n;i++)
{
if(i%2 == 1) // alice
{
if(evc>=1 && ev[evc]>=od[odc])
{
aans+=ev[evc];
evc--;
}
else
{
odc--;
}
}
else // bob
{
if(odc>=1 && od[odc]>=ev[evc])
{
bans+=od[odc];
odc--;
}
else
{
evc--;
}
}
}
if(aans == bans)
{
cout<<"Tie"< bans)
{
cout<<"Alice"<
https://codeforces.com/contest/1472/problem/E
思路:不管坐着躺着,都统一为第一维度(x)是二者中小的数,第二维度(y)是二者中大的数,并以x升序,y降序进行排序处理,非常巧妙,是通过这个方式来保证,tid所标记的点,在当前状态下,其y值是最小的(由于x有序,所以x一定是小于的),这样来判断,如果满足题述要求便记录答案,不满足则更新tid值(以获得更小的b值),从而实现了时间复杂度的降维。
#include
#include
#include
using namespace std;
struct peo{
long long x,y;
long long id;
}p[300005];
long long ans[300005];
bool cmp(peo a,peo b)
{
if(a.x == b.x)
return a.y>b.y;
return a.x>T;
while(T--)
{
long long n;
scanf("%lld",&n);
long long ta,tb;
for(long long i=1;i<=n;i++)
{
scanf("%lld%lld",&ta,&tb);
p[i].id=i;
p[i].x=min(ta,tb);
p[i].y=max(ta,tb);
}
sort(p+1,p+n+1,cmp);
int tid=1;
for(long long i=1;i<=n;i++)
{
long long t=-1;
if(p[i].y > p[tid].y)
{t=p[tid].id;}
if(p[i].y < p[tid].y)
{tid=i;}
ans[p[i].id] = t;
//printf("%s\n", );
}
for(long long i=1;i<=n;i++)
{
printf("%lld",ans[i]);
if(i!=n) printf(" ");
}
cout<