5.24 省赛组队训练(1)

来源:互联网 发布:mac切换字母和拼音 编辑:程序博客网 时间:2024/06/06 20:19

本次模拟的是cf第200场的题:http://codeforces.com/contest/344

A:水题

大意:看能组成几个磁铁块,如果连续几个一样的摆放方式这些就都被归为一块,那么主要就在于找出几个这样的块,换个说法就是找出几个突变的就可以了,(当然input中的第一个自己也算一个突变)

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int main(){    int n;    while(scanf("%d",&n)==1)    {        char s[5];        scanf("%s",s);        char temp = s[0];        int ans = 1;        for(int i = 1;i < n;i++)        {            scanf("%s",s);            if(s[0]!=temp) ans++;            temp = s[0];        }        printf("%d\n",ans);    }    return 0;}

B题:图片是用来混淆你的题

题目 大意:每个分子由几个原子组成,原子与其他原子之间可以相互成键(但是原子不能跟自己成键),然而每个原子总共成的键要跟他的化合价相等。

给出了三个原子的价态,要求输出1-2间,2-3,3-1间的键有几个。

这其实就是一个三个未知量解方程的方法吧。

首先每个原子的价态定义为a,b,c。1-2 ,2-3,3-1间分别有x,y,z个键

那么得到:z+x=a,x+y=b,y+z=c

我的思路是直接先解出z,z = (c+a-b)/2;然而此时z可能根本不是整数,先不管,根据z在解出x,y。最后判断解是否合理(都大于零)且z和另外随便一个是否满足的等式。

这样就能避免z不是整数的情况了

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int main(){    int a,b,c;    while(scanf("%d %d %d",&a,&b,&c)==3)    {        int x,y,z;        z = (c+a-b)/2;        x = a-z;        y = b-x;        if(z>=0 && x>=0 && y>=0 && y+z==c) //验证第三个等式是否相等,一开始wa在没有判断,结果还以为题目读错了,搞了好久。。            printf("%d %d %d\n",x,y,z);        else            printf("Impossible\n");    }    return 0;}

还看到前几名的一种:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespace std;int main(){int a1, a2, a3;int b12, b23, b31;cin >> a1 >> a2 >> a3; //a1=b12+b31 a2=b23+b12 a3=b31+b23int sum = a1 + a2 + a3;if(sum % 2 != 0)  //表示b12 b21 b31 中肯定有不是整数的数{cout << "Impossible";return 0;}sum /= 2; //此时sum=b12+b23+b31b12 = sum - a3; b23 = sum - a1;b31 = sum - a2;if(b12 < 0 || b23 < 0 || b31 < 0)cout << "Impossible";elsecout << b12 << " " << b23 << " " << b31 << endl;return 0;}

C题

数学题:就是找出需要最少多少个电阻才能拼成所需要的阻值。

可以知道的是a/b,b/a所需要的最少的阻值其实是一样的,因为并联的话可以直接上下翻转一下就好。

还有就是1/b和b的话都是最少只需要b个的。

那么我的思路就是将所需要的阻值一直转化成假分数,因为反正上下颠倒要的个数也是一样的。那么每次去掉他所需要的整数部分,这个就是当前要的最少的,然后整数部分去掉之后我们又得到一个真分数,在重复之前的操作,直到这个数就是一个整数,直接加上他本身。这样最后就能找出所需要的最小的阻值。

一开始wa在第四组,我还以为思路错了,结果发现是输入没有用longlong int 千万要小心啊。。。别犯低级错误。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define ll long longll sum;int main(){    ll n,m;    while(cin >> n >> m)    {        sum = 0;        //cout << f(n,m) << endl;        ll a = n, b = m;        /*while(1)        {            if(a < b) swap(a,b);            ll d = a/b;            ll c = a%b;            if(c==0)            {                sum+=d;                break;            }            else            {                sum += d;                a = c;            }        }*///之前写的渣代码 一点都不优美while(a) //优美版        {            if(a < b) swap(a,b);            sum += a/b;            a = a%b;        }        cout << sum << endl;    }    return 0;}
递归实现:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define ll long longll sum;ll f(ll a,ll b){    if(a < b) swap(a,b);    ll d = a/b;    ll c = a%b;    if(c==0) return d;    else    {        return (f(c,b)+d);    }}int main(){    ll n,m;    while(cin >> n >> m)    {        sum = 0;        cout << f(n,m) << endl;    }    return 0;}

D题:

用一个栈来模拟,我自己没有实现,是队友做的,感觉还是思路还是比较酷的。

对于每个符号来说,如果他跟栈顶元素相同的话,那么就可以将栈顶元素弹出(意味着这两个相邻的可以被解开),如果栈是空的话或者与栈顶元素不相同,那么就将这个元素压入栈。这样的话所有元素输入之后,判断下栈是不是空的,如果是空的意味着都解开了,yes。反之no

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <stack>#include <queue>#include <map>#include <set>#include <sstream>#include <math.h>#include <algorithm>using namespace std;stack<char> sta;int main() {    char ch;    ch = getchar();    sta.push(ch);    while((ch = getchar()) != '\n') {        if(!sta.empty() && ch == sta.top()) {            sta.pop();        }        else {            sta.push(ch);        }    }    if(sta.empty()) {        printf("Yes\n");    }    else {        printf("No\n");    }}


0 0
原创粉丝点击