16.7.20

来源:互联网 发布:Java restpath 编辑:程序博客网 时间:2024/04/28 18:47

二分查找

int bSearch(int arr[],int value,int begin,int end){    if(begin > end) return -1;    int mid = (begin+end)/2;    if(arr[mid] == value)         return middle;    else if(arr[mid] > value)         return bSearch(arr,value,begin,mid-1);      else if(arr[mid] < value)        return bSearch(arr,value,mid+1,end);}

//今日代码
2016-07-20 personal training

A. I_love_\%username\%

(当分数比目前分数的最高还高或最低还低则惊讶,求惊讶值。对每个数每次和max和min对比顺带更新下最大最小值)

#include<iostream> #include<cstdio>#include<string>#include<algorithm>#include<cmath>#include<cstring>#include<map>#define LL long long #define INF 0x1f1f1f1fusing namespace std;int arr[1010];int main(){    int n;    cin >> n;    for(int i = 0;i < n; i++)        cin >> arr[i];    int Max = arr[0];    int Min = arr[0];    int ans = 0;    for(int i = 1; i < n; i++)    {        if(arr[i] > Max)        {            Max=  arr[i];            ans++;        }        else if(arr[i] < Min)        {            Min = arr[i];            ans++;        }    }    cout << ans << endl;    return 0;   }

B. Combination

(对每个卡牌,给定次张卡牌的分和接下来能玩的卡牌个数。按接下来能玩个数和分数由高到低排序,每次取卡牌加分同时计算接下来的个数。)

#include<iostream> #include<cstdio>#include<string>#include<algorithm>#include<cmath>#include<cstring>#include<map>#define LL long long #define INF 0x1f1f1f1fusing namespace std;struct card{    int score;    int num;}c[1010];bool compare(const card & c1, const card & c2){    if(c1.num > c2.num) return true;    else if(c1.num == c2.num && c1.score > c2.score)        return true;    return false; }int main(){    freopen("xx.in","r",stdin);    freopen("xx.out","w",stdout);    int n;    cin >> n;    for(int i = 0; i < n; i++)        scanf("%d%d",&c[i].score,&c[i].num);    sort(c,c+n,compare);     int cnt = c[0].num;    int sum = c[0].score;    int i = 1;    while(cnt > 0 && i < n)    {           sum += c[i].score;        cnt += c[i].num;        cnt--;         i++;    }    cout << sum << endl;    return 0;   }

C. Hometask

(对一个字符串求不能使n对给定字符相接,需要去除的字符个数。可以发现无论是同个字符连一起aabbb还是岔开babbaba的情况其实都不得不把较少的那个字符全部删掉。ac代码即暴力orz 复杂度O(N))

#include<iostream> #include<cstdio>#include<string>#include<algorithm>#include<cmath>#include<cstring>#include<map>#define LL long long #define INF 0x1f1f1f1fusing namespace std;int main(){    freopen("xx.in","r",stdin);    freopen("xx.out","w",stdout);    string s;    cin >> s;    int n;    cin >> n;    int ans = 0;    while(n--)    {        char a, b;        cin >> a >> b;        for(int i = 0; i < s.length() ; i++)        {            int l = 0,r = 0;            while(s[i] == a || s[i] == b)            {                   if(s[i] == a) l++;                if(s[i] == b) r++;                 i++;            }            ans+=min(l,r);        }    }    cout << ans<< endl;    return 0;   }

D. Colliders

(难点在于对没开机的飞机进行开机操作时,判断下是否会和已开机的飞机相撞。即怎么不超时的判断两个数是否互质,每次都判一定会t..不管怎么判都t,每次还t在不同的点orz 正确思路是分解质因数并记录,如果有相同的质因数则会相撞。要做到不相撞,则必须保证每个质因数都只被一台飞机占有,所以记录的方法是对编号为n的飞机,把在分解n时得到质因数标记为编号n,在关机时在把这些质因数的标记清为零。下面的代码有参考别人博客,其中有对每个编号的飞机记录下它有的质因数个数,其实好像不是很必要。)

(下面是另一个清晰易懂的实现方法:

考虑每个对撞机的因数分解
一个int数组vis1,一个bool数组vis2
vis2数组存放每个对撞机的状态on/off
vis[i]存放的是占领 i 这个下标的对撞机的编号,因为所有开启的对撞机编号都互质,所以每个下标 i 至多只能有一个对撞机占领
1、对于开启操作+ c,我们只要枚举 c 除 1 以外的所有因子,查看vis1中那些因子所在位置是否被占领,若是没有被占领,那 c 这个对撞机便可开启
vis1[c的所有因子] = c, vis2[c] = 1;
2、对于关闭操作- c ,首先判断 c 是否开启,若是开启就将其关闭
vis1[c的所有因子] = 0, vis2[c] = 0;
由于(1 <= n ,m <= le5)我们可以直接
for i = 2 to sqrt(c) 枚举因子
复杂度O(m * sqrt(n));

#include<iostream> #include<cstdio>#include<string>#include<algorithm>#include<cmath>#include<cstring>#include<map>#include<set>#define LL long long #define INF 0x1f1f1f1fusing namespace std;#define N 100010bool p[N];bool isprime[N];bool islive[N];int cnt[N];int prime[N];int data[N][10];int len = 0;void initpri(){    memset(isprime,1,sizeof(isprime));    for(int i = 2; i < N/2; i++)    {        if(isprime[i])        {            for(int j = 2*i; j < N ;j+=i)                 isprime[j] = false;        }    }    for(int i = 2; i < N; i++)    {        if(isprime[i]) prime[len++] = i;    }    for(int i = 0;i < len;i++)      {          for(int j = prime[i];j < N; j += prime[i])              data[j][++data[j][0]] = prime[i];    }  }int main(){    freopen("xx.in","r",stdin);    freopen("xx.out","w",stdout);    int n,m;    cin >> n >> m;    initpri();     getchar();    char c;    int num;    for(int i = 0 ; i < m ; i++)    {        scanf("%c %d",&c, &num);        getchar();        if(c == '+')        {                   if(islive[num])                printf("Already on\n");            else            {                bool flag = 0;                  for(int j = 1;j <= data[num][0];j++)                         if(cnt[data[num][j]])                         {                             printf("Conflict with %d\n",cnt[data[num][j]]);                             flag = true;                           break;                         }                     if(!flag)                     {                         for(int j = 1;j <= data[num][0];j++)                             cnt[data[num][j]] = num;                         printf("Success\n");                         islive[num] = true;                   }              }        }        else if(c == '-' && !islive[num])            printf("Already off\n");        else if(c == '-' && islive[num])        {            for(int j = 1;j <= data[num][0];j++)                  cnt[data[num][j]] = 0;             islive[num] = false;            printf("Success\n");        }    }    return 0;   }

F. DZY Loves Chessboard

(本来直接模拟,对于每个好棋盘空格都判一下上下左右是否有相同然后谜一样的wa..后来发现这种思路,简单易懂不易出错。就是直接判能放,则按对角线排B和W,i+j为奇数时排一种,偶数时排另一种。)

#include<cstdio>#include<iostream> #include<string>#include<algorithm>#include<cmath>#include<cstring>#include<map>#define LL long long #define INF 0x1f1f1f1fusing namespace std;char arr[110][110];int main(){    freopen("xx.in","r",stdin);    freopen("xx.out","w",stdout);    int n,m;    cin >> n >> m;    getchar();    for(int i = 1; i <= n; i++)    {        for(int j = 1; j <= m; j++)            arr[i][j] = getchar();        getchar();    }    for(int i = 1; i <= n; i++)        for(int j = 1; j <= m ; j++)        {            if(arr[i][j] == '.')            {                if((i+j)%2) arr[i][j] = 'B';                else arr[i][j] = 'W';            }         }    for(int i = 1; i <= n; i++)    {        for(int j = 1; j <= m ; j++)            printf("%c",arr[i][j]);        printf("\n");    }    return 0;   }

G. DZY Loves Chemistry

(题意是有n中化学药品,其中m对两两会发生反应,若不会反应则危险值为1,在加入药剂过程中,反应一次危险值×2。连通块问题,下面的代码用了并查集。 对于每个结点之间能发生关系的看做连边,便能形成M个连通块,ans为结点数N减去连通块个数M即该连通块的边数,所求答案为2^ans。arr[i]存的是 i 的父节点,遍历每个父节点,它的子节点个数就是该连通块的边数。)

#include<iostream> #include<cstdio>#include<string>#include<algorithm>#include<cmath>#include<cstring>#include<map>#define LL long long #define INF 0x1f1f1f1fusing namespace std;int arr[55];//寻找连通点 int find(int a){    if(arr[a] == a) return a;    else return arr[a] = find(arr[a]); }//更新连通点 void check(int a, int b){    int aa = find(a);    int bb = find(b);    if(aa != bb) arr[aa] = bb;}int main(){    freopen("xx.in","r",stdin);    freopen("xx.out","w",stdout);    int n,m ;    cin >> n >> m;    for(int i = 1; i <=n; i++)        arr[i] = i;    int a , b;    while(m--)    {        cin >> a >> b;        check(a,b);    }    long long ans = 1;    for(int i = 1; i <= n; i++)    {        if(arr[i] == i)            for(int j = 1; j <= n; j++)                 if(i!=j && find(j) == arr[i])                       ans*=2;    }    printf("%I64d\n",ans);    return 0;   }
0 0
原创粉丝点击