2017多校7-三道水题

1005:Euler theorem

题意:给一个数a,求(a%x)的值有多少种。

分析:对于大于a/2的数,设为t,那么a%t =(a- t).对于小于等于a/2的数t,必然存在一个整数z,使得 z*ta,z*t>a,此时答案就是 a-z*t.(前面已出现的答案)。

对于大于a的数,a%t = a。所以答案就呼之欲出了。

#include 
#include 
#include 
#include 
#include 
#include 
#define siz 100005
#define LL long long

using namespace std;
int n,m;
 int euler(int n){
     int res=n,a=n;
     for(int i=2;i*i<=a;i++){
         if(n%i==0){
             res=res/i*(i-1);
             while(n%i==0) n/=i;
         }
     }
     if(n>1) res=res/n*(n-1);
     return res;
}
int main()
{
        int t,a;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&a);
        printf("%d\n",(a+1)/2+1);
    }
    return 0;
}

1011:Kolakoski

题意:给一组数,让你求第n的数。

规律:

Kolakoski序列是一个仅由1和2组成的无限数列,是一种通过“自描述”来定义的数列 。他的前几项为
1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1,2,1,1,2,1,2,2,1,1,…( OEIS上的A000002)
它的定义很简单,若把数列中相同的数定为一组,令a(1)=1,a(2)=2,则a(n)等于第n组数的长度。
可以根据这个定义来推算第三项以后的数:例如由于a(2)=2,因此第2组数的长度是2,因此a(3)=2,;
由于a(3)=2,所以第三组数的长度是2,因此a(4)=a(5)=1;由于a(4)=1,a(5)=1,所以第四组数和第五组数的长度都为1,因此a(6)=2,a(7)=1,以此类推

#include 
#include 
#include 
#include 
#include 
#include 
#define siz 10000100
#define LL long long

using namespace std;
int gp[siz];
int x[siz];
void solve(){
    gp[1] = 1;
    gp[2] = 2;
    //gp[3] = 2;
    x[1] = 1;
    int i = 2;
    int j = 2;
    int flag = 2;
    while(j
1008:题意:给n个坐标点,以及这个点的价值v,定义两个点之间的价值是vi*vj。现让你画一条过原点的的直线,将平面上的点分成两部分,然后将两部分之间 的两两之间求价值,使得价值最大。

分析:对于平面上所有的点,必然会存在一条直线将他们分成两部分,所以我们可以枚举分成的这些两部分。维护一个最大值。

然后,那条线必然是穿过1,3象限或者2,4象限。我们可以将每个点与原点连线,求得一个斜率,然后按照斜率从小到大排序,开始的那条直线可以先平行于x轴开始,再平行于y轴开始,旋转,每次旋转一个当前两个象限斜率小的那个点,而对于答案,对于条直线分成的两部分,设价值和分别为sum1和sum2,那么答案自然是sum1*sum2.而当我们旋转过一个点时,设转 过斜率的价值和为v(在那个斜率的直线上可能有很多点),那么价值为 (sum2 - v) *(sum1+v).暴力分两次更新就行。

#include 
#include
#include
#include
#define siz 105
const int maxn = 50000;
const double infk = 2000000000;
typedef long long LL;
using namespace std;
struct node
{
    int x,y,w;
    double k;
} G[5][maxn+5];
/*
5
8
2 2 2
1 1 2
3 0 100
1 -2 10
-1 1 5
-1 0 5
-1 -1 10
-1 3 10
*/
int n,tot[5];
LL ans;
int isg(int x,int y)
{
    if(x>=0&&y>=0) return 1;
    if(x<0&&y>=0) return 2;
    if(x<0&&y<0) return 3;
    if(x>=0&&y<0) return 4;
    return 0;
}
double fk(int x,int y)
{
    if(x) return y*1.0/x*1.0;
    return infk*1.0;
}
bool cmp(node A,node B)
{
    return A.k < B.k;
}
void finmin(int &s1,int &s2,LL&cot1,LL&cot2,int g1,int g2)
{
    int i;
    G[g1][tot[g1]+1].k = infk+105;
    G[g2][tot[g2]+1].k = infk+105;
    if(G[g1][s1+1].k*1.0G[g2][s2+1].k)
        {
            for(i=s2+1;G[g2][i].k==G[g2][s2+1].k; i++) cot2+=G[g2][i].w;
            s2=i-1;
        }
        else
        {
            for(i=s1+1; G[g1][i].k==G[g1][s1+1].k; i++) cot1+=G[g1][i].w;
            s1=i-1;
            for(i=s2+1; G[g2][i].k==G[g2][s2+1].k; i++) cot2+=G[g2][i].w;
            s2=i-1;
        }
    }
}
void ok(int g1,int g2,LL sum1,LL sum2)
{
    LL cot1,cot2;
    int s1=0,s2=0;
    while(s1

你可能感兴趣的:(2017杭电多校训练)