The 19th Zhejiang University Programming Contest
A题
每个人只能和异性配对,且有必须与比自己高/矮的人配对,求最大配对数。
贪心,排序后配对即可。
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define N 100010
using namespace std;
const int M = 1e9+7;
int t;
int cnt;
int mal0[N],fem0[N],mal1[N],fem1[N];
int a[N],b[N];
int n,m;
int n0,n1,m0,m1;
inline void init(){
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",&b[i]);
int tmp;
n0=m0=n1=m1=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&tmp);
if(!tmp) mal0[++n0]=a[i];
else mal1[++n1]=a[i];
}
for(int i=1;i<=m;i++)
{
scanf("%d",&tmp);
if(!tmp) fem0[++m0]=b[i];
else fem1[++m1]=b[i];
}
sort(mal0+1,mal0+n0+1);
sort(mal1+1,mal1+n1+1);
sort(fem0+1,fem0+m0+1);
sort(fem1+1,fem1+m1+1);
cnt=0;
}
inline void compair(){
int p=1,q=1;
while(p<=n0 && q<=m1)
{
if(mal0[p] > fem1[q])
{
cnt++;
++p;++q;
}
else
{
++p;
}
}
p=q=1;
while(p<=n1 && q<=m0)
{
if(mal1[p] < fem0[q])
{
cnt++;
++p;++q;
}
else
{
++q;
}
}
}
int main(){
scanf("%d",&t);
while(t--)
{
init();
compair();
printf("%d\n", cnt);
}
return 0;
}
B题
规律+大数
每次/2,然后将这个数加入计数中。
//主程序
int main()
{
int t;
scanf("%d",&t);
BigNum e;
BigNum cnt;
cnt = 0;
while(t--)
{
cin >> e;
while(e > 0)
{
e = e/2;
cnt = cnt + e;
}
cout << cnt << endl;
cnt = 0 ;
}
return 0;
}
C题
大模拟
和队友到最后冲不动了,大家都不想写…
E题
签到
#include
#include
#include
using namespace std;
int T,n;
long long a[120],b[120];
bool fg=true;
int main(){
cin>>T;
while(T--){
fg=true;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
cin>>n;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=1;i<=n;i++){
scanf("%lld",&b[i]);
}
for(int i=n;i>=2;i--){
if(b[i]<a[i]){
fg=false;
break;
}
b[i-1]+=b[i]-a[i];
}
if(b[1]<a[1])fg=false;
if(fg) printf("Yes\n");
else printf("No\n");
}
return 0;
}
J题
签到
#include
using namespace std;
int main()
{
long long x,y,n,t,i;
long long ans1[100001];
long long ans2[100001];
cin>>t;
for (i=1;i<=t;i++)
{
scanf("%lld",&n);
if (n%2==0) {ans1[i]=4;ans2[i]=4+n;}
else {ans1[i]=9;ans2[i]=9+n;}
}
for (i=1;i<=t;i++) printf("%lld %lld\n",ans1[i],ans2[i]);
return 0;
}
G题
思维+贪心
正负分开,首先找到最后k封信,删去回去的长度即可。
wa了好多发,质疑过算法后,发现没开LL(还是不能太相信数据范围)
#include
#include
#include
#include
#define ll long long
using namespace std;
ll T,n,k,cnt1,cnt2;
ll a[100020],b[100020];
ll cmp(ll x,ll y){
return x>y;
}
ll cmp1(ll x,ll y){
return x<y;
}
long long ans;
int main(){
ll xx;
scanf("%lld",&T);
while(T--){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
ans=cnt1=cnt2=0;
scanf("%lld%lld",&n,&k);
for(ll i=1;i<=n;i++){
scanf("%lld",&xx);
if(xx>0){
a[++cnt1]=xx;
}
else if(xx<0){
b[++cnt2]=xx;
}
}
sort(a+1,a+1+cnt1,cmp);
sort(b+1,b+1+cnt2,cmp1);
ll ii=1,jj=1;
if(a[1]>-b[1]){
ans+=a[1],ii=k+1;
}
else ans+=-b[1],jj=k+1;
for(ii;ii<=cnt1;ii+=k){
if(ii>cnt1) break;
ans+=a[ii]*2;
}
for(jj;jj<=cnt2;jj+=k){
if(jj>cnt2) break;
ans+=(-b[jj])*2;
}
printf("%lld\n",ans);
}
return 0;
}