第一次过三题..记录一下! 16周了..要开始考试了..
网址: http://codeforces.com/contest/743
第一题 直接找规律,
#include <cstring>
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + 5;
int main()
{
int n;
int a, b;
char x[maxn];
scanf("%d%d%d%*c", &n, &a, &b);
scanf("%s", x);
if (x[a - 1] == x[b - 1])
puts("0");
else puts("1");
return 0;
}
1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 循环,就是一开始是1,然后每次复制一次放后面变成11,然后在中间插入最小切不重复的正整数变成121,重复,问第k个数
比赛的时候用的方法是. 先把大数转成二进制数,然后从后面开始判断第几个二进制数是1 ,
ans k
1: 1 3 5 7 9 11 ----2
2: 2 6 10 14 18 22 ----4
3: 4 12 20 28 ----8
4: 8 24 40 56 ----16
5: 16 ----24
一开始发现规律是这样的,但是没什么用,然后想到应该还是跟位运算有关,因为这里面出现了很多二.
然后把每个数写成二进制代码,发现其实就是按照从右往左找第一个为1的数,然后找了个大数求二进制数的代码...贴了进去..就过了
不过后来网上看到这个就是跟 lowbit 的求法一个意思..学起来!
/*
直接用lowbit很快,直接取出一个数二进制中的最后一个1,树状数组常用
/owbit(x)=x&-x;
Lowbit(6) = 2^1 = 2
*/
原来的解: 麻烦..
#include <cstring>
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
char binvec[1001];
//http://blog.youkuaiyun.com/ubuntuqqqq/article/details/45723477
//把十进制的大数转化成二进制数
//直接用lowbit很快,直接取出一个数二进制中的最后一个1,树状数组常用
//lowbit(x)=x&-x;
//Lowbit(6) = 2^1 = 2
void tenToBin(string str)
{
int j = 0;
int sum = 1;
int len = str.size();
while (sum) {
sum = 0;
for (int i = 0; i<len; ++i) {
int temp = (str[i] - '0') / 2;
sum += temp;
if (i == len - 1) {
binvec[j++] = (str[i] - '0') % 2 + '0';
}
else {
str[i + 1] = str[i + 1] + (str[i] - '0') % 2 * 10;//算出下一个被除数
}
//记录该次得出的商
str[i] = temp + '0';
}
}
}
void resout()
{
//逆序
int len1 = strlen(binvec);
for (int i = 0, j = len1 - 1; i<len1 / 2; ++i, --j) {
char temp = binvec[j];
binvec[j] = binvec[i];
binvec[i] = temp;
}
}
int main()
{
int n;
cin >> n;
getchar();
string str;
cin >> str;
memset(binvec, '\0', sizeof(binvec));
tenToBin(str);
resout();
int len = strlen(binvec);
int cnt = 1;
for (int i = len - 1; i >= 0; i--)
{
if (binvec[i] == '1')
break;
else cnt++;
}
printf("%d", cnt);
return 0;
}
看别人很快的解法
/*
其实直接用long long 也可以, 2^50也不会爆,不一定要用数组
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long ll;
int main()
{
ll n;
cin >> n;
cin >> n;
int k = 0;
while(((n >> k) & 1) == 0) k++;
printf("%d\n", k + 1);
//cin >> n;
return 0;
}
用lowbit重新实现一遍
#include <cstring>
#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
ll lowbit(ll x)
{
return x&-x;
}
int main()
{
ll n;
scanf("%I64d", &n);
ll k;
scanf("%I64d", &k);
ll x = lowbit(k);
int cnt = 0;
while (x)
{
x /= 2;
cnt++;
}
printf("%d", cnt);
return 0;
}
题意: n的倒数的两倍用三个数的倒数和表示
想了一下,把其中一个数也用成n,然后就变成1/n=1/x+1/y;
其实就是1/n=1/(n+1) + 1/n*(n+1)
一开始忘了排除1 , 重判的时候WA了,然后改加上特判1就可以了
#include <cstring>
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
typedef long long ll;
int main()
{
ll n;
scanf("%I64d", &n);
if (n == 1)
puts("-1");
else
printf("%I64d %I64d %I64d", n, n + 1, n*(n + 1));
return 0;
}