codeforces #242 abcd

A:
题目大意:统计x的个数是不是总数一半,不是的话要变成一半所需改变次数以及改变后的序列
代码:
#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
    char c[220];
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        cin>>c;
        int sum=0;
        for(int i=0;i<n;i++)
        {
            if(c[i]=='x')
            sum++;
        }
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            if(sum<n/2)
            {
                for(int i=0;i<n;i++)
                {
                    if(sum==n/2) break;
                    if(c[i]=='X')
                    {
                        c[i]='x';
                        sum++;
                        cnt++;
                    }
                }
            }
            else if(sum>n/2)
            {
                for(int i=0;i<n;i++)
                {
                    if(sum==n/2) break;
                    if(c[i]=='x')
                    {
                        c[i]='X';
                        sum--;
                        cnt++;
                    }
                }
            }
        }
        cout<<cnt<<endl;
        cout<<c<<endl;
    }
    return 0;
}
题目大意:给出城市(0,0),给出n个坐标,起始人数s,每个坐标k个人, 每个坐标可以覆盖到半径为r的区域,r=sqrt(x*x+y*y)的区域,问最小的半径是多少,使得城市的总人数大于等于1000000;
贪心排序即可;
代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
struct node
{
    int x,y;
    double r;
    int num;
}data[1010];
int cmp(const node &a,const node &b)
{
    return a.r<b.r;
}
int main()
{
    int n,s;
    while(cin>>n>>s)
    {
        for(int i=0;i<n;i++)
        {
            cin>>data[i].x>>data[i].y>>data[i].num;
            data[i].r=sqrt(data[i].x*data[i].x+data[i].y*data[i].y);
        }
        sort(data,data+n,cmp);
        for(int i=0;i<n;i++)
        {
            s+=data[i].num;
            if(s>=1000000)
            {
                printf("%.7lf\n",data[i].r);
                break;
            }

        }
        if(s<1000000)
        cout<<"-1"<<endl;
    }
    return 0;
}
题目大意:题意:给出n个整数p1~pn,求Q。公式如图, 表示x异或y,即x^y。
此处借鉴别人的,觉得简单易懂,很好

分析:设  为公式1,

 为公式2.     

因为异或运算满足交换律,

所以公式2 = p1^p2^……^pn^(1%1)^(1%2)^……(1%n)^(2%1)%(2%2)^……^(2%n)^……^(n%1)^(n%2)^……^(n%n)

 =p1^p2^……^pn^(1%1)^(2%1)^……(n%1)^(1%2)^(2%2)^……^(n%2)^……^(1%n)%(2%n)^……^(n%n)

又因为对于任何一个正整数k,(1~n) % k 只会有0~(k-1)这k种结果,所以(1%k)、(2%k)……(n%k)是有规律的,也就是(1%k)^(2%k)^……^(n%k)是有规律的。

例如当n=15,k=7时,(1%k)、(2%k)……(n%k)的结果如下表所示。

1

2

3

4

5

6

0

1

2

3

4

5

6

0

1

 

 

 

 

 

 



根据异或原则,a^a=0,0^a=a; 所以图中红色两行异或结果为0。所以(1%7)^(2%7)^……^(15%7)=1;

又如当n=25,k=7时。(1%7)、(2%7)……(25%7)的结果如下表。

1

2

3

4

5

6

0

1

2

3

4

5

6

0

1

2

3

4

5

6

0

1

2

3

4

 

 

 



所以 1%7)^(2%7)^……^(25%7) = 5^6^0 = 3

因此,在处理这个问题时,可以用一个数组a保存1异或到n的结果,然后枚举k=1~n,求出余数为0~(k-1)的有多少个整行,最后把不足一整行的那部分计算进去就行了。
代码:
#include <iostream>
#include <stdio.h>
using namespace std;
const int maxn=1e6+10;
int a[maxn];
int main()
{
   a[0]=0;
   for(int i=1;i<=maxn;i++)
   a[i]=a[i-1]^i;
   int n,k;
   while(cin>>n)
   {
       int ans=0;
       for(int i=1;i<=n;i++)
       {
           scanf("%d",&k);
           ans^=k;
           if((n/i)&1) ans^=a[i-1];
           ans^=a[n%i];
       }
       cout<<ans<<endl;
   }
    return 0;
}
D:
题目大意:

给你一个N×M的矩阵,上面有数字,从大的到小的要花费td,从小的到大的要花费tu,大小一样花费tp

要你这一个顺时针的圈,使这个花费加起来最接近t,四个边都要>=3

解题思路:暴力,先处理四个方向,然后暴力枚举四个点
ps:abs做好自己写,不然容易TLE;
代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
struct node
{
    int l,r,d,u,v;
} data[310][310];
int fabs2(int x)
{
    if(x<0) x=-x;
    return x;
}
int main()
{
    int t,n,m;
    while(scanf("%d%d%d",&n,&m,&t)!=EOF)
    {
        int tp,tu,td;
        scanf("%d%d%d",&tp,&tu,&td);
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                scanf("%d",&data[i][j].v);
                data[i][j].u=data[i][j].d=data[i][j].l=data[i][j].r=0;
            }
        }
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if(i!=1)
                {
                    if(data[i-1][j].v==data[i][j].v)
                        data[i][j].u=data[i-1][j].u+tp;
                    else if(data[i-1][j].v<data[i][j].v)
                        data[i][j].u=data[i-1][j].u+tu;
                    else
                        data[i][j].u=data[i-1][j].u+td;
                }
                if(i!=1)
                {
                    if(data[i-1][j].v==data[i][j].v)
                        data[i][j].d=data[i-1][j].d+tp;
                    else if(data[i-1][j].v>data[i][j].v)
                        data[i][j].d=data[i-1][j].d+tu;
                    else
                        data[i][j].d=data[i-1][j].d+td;
                }
                if(j!=1)
                {
                    if(data[i][j-1].v==data[i][j].v)
                        data[i][j].l=data[i][j-1].l+tp;
                    else if(data[i][j-1].v<data[i][j].v)
                        data[i][j].l=data[i][j-1].l+tu;
                    else
                        data[i][j].l=data[i][j-1].l+td;
                }
                if(j!=1)
                {
                    if(data[i][j-1].v==data[i][j].v)
                        data[i][j].r=data[i][j-1].r+tp;
                    else if(data[i][j-1].v<data[i][j].v)
                        data[i][j].r=data[i][j-1].r+td;
                    else
                        data[i][j].r=data[i][j-1].r+tu;
                }
            }
        }
        int x1,x2,y1,y2;
        int ans=2000000000;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                for(int ii=i+2; ii<=n; ii++)
                {
                    for(int jj=j+2; jj<=m; jj++)
                    {

                        int tmp=fabs2(t-(data[i][jj].l-data[i][j].l+data[ii][jj].r-data[ii][j].r+data[ii][jj].u-data[i][jj].u+data[ii][j].d-data[i][j].d));
                        if(ans>tmp)
                        {
                            ans=tmp;
                            x1=i;
                            y1=j;
                            x2=ii;
                            y2=jj;
                        }
                    }
                }
            }
        }
        printf("%d %d %d %d\n",x1,y1,x2,y2);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值