codeforces #242 abcd

A:
链接: http://codeforces.com/problemset/problem/424/A
题目大意:统计x的个数是不是总数一半,不是的话要变成一半所需改变次数以及改变后的序列
代码:
#include 
#include 
using namespace std;

int main()
{
    char c[220];
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        cin>>c;
        int sum=0;
        for(int i=0;in/2)
            {
                for(int i=0;i
B: http://codeforces.com/problemset/problem/424/B
题目大意:给出城市(0,0),给出n个坐标,起始人数s,每个坐标k个人, 每个坐标可以覆盖到半径为r的区域,r=sqrt(x*x+y*y)的区域,问最小的半径是多少,使得城市的总人数大于等于1000000;
贪心排序即可;
代码:
#include 
#include 
#include 
#include 
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>n>>s)
    {
        for(int i=0;i>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=1000000)
            {
                printf("%.7lf\n",data[i].r);
                break;
            }

        }
        if(s<1000000)
        cout<<"-1"<
C:链接: http://codeforces.com/problemset/problem/424/C
题目大意:题意:给出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 
#include 
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<
D:
链接: http://codeforces.com/problemset/problem/424/D
题目大意:

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

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

解题思路:暴力,先处理四个方向,然后暴力枚举四个点
ps:abs做好自己写,不然容易TLE;
代码:
#include 
#include 
#include 
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].vdata[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].vtmp)
                        {
                            ans=tmp;
                            x1=i;
                            y1=j;
                            x2=ii;
                            y2=jj;
                        }
                    }
                }
            }
        }
        printf("%d %d %d %d\n",x1,y1,x2,y2);
    }
    return 0;
}


你可能感兴趣的:(codeforces)