一、
Sherlock and Watson are playing the following modified version of Nim game:
Giving the initial situation of each game, you are required to figure out who will be the winner
The first contains an integer, g, denoting the number of games. The 2×g subsequent lines describe each game over two lines:
1. The first line contains a prime integer, n, denoting the number of piles.
2. The second line contains n space-separated integers describing the respective values of ,,...,.
For each game, print the name of the winner on a new line (i.e., either "Sherlock
" or "Watson
")
2 3 2 3 2 2 2 1
Sherlock Watson
Nim博弈:
如果石子堆们异或为0, 则先手必输。
威佐夫博弈:
对于两堆石子n1
#include
using namespace std;
#define N 100001
int main()
{
int n, a[N], b, c;
int t;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
if(n == 2){
scanf("%d%d", &b, &c);
if(b > c)
swap(b, c);
if(int((c - b) * (1 + sqrt(5.0)) / 2.0) == b)
printf("Watson\n");
else
printf("Sherlock\n");
}
else{
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
int ans = a[0];
for(int i = 1; i < n; i++)
ans ^= a[i];
printf(!ans?"Watson\n":"Sherlock\n");
}
}
return 0;
}
With given integers a,b,c, you are asked to judge whether the following statement is true: "For any x, if a⋅+b⋅x+c=0, then x is an integer."
The first line contains only one integer T(1≤T≤2000), which indicates the number of test cases.
For each test case, there is only one line containing three integers a,b,c(−5≤a,b,c≤5).
or each test case, output “YES
” if the statement is true, or “NO
” if not.
3 1 4 4 0 0 1 1 3 1
YES YES NO
这题真尼玛坑爹,WA了一万遍,竟然卡精度了。
另外无数解的情况算假,无解的情况算真。
#include
using namespace std;
int main()
{
freopen("date.txt", "r", stdin);
int a, b, c, t;
scanf("%d", &t);
while(t--){
scanf("%d%d%d", &a, &b, &c);
double qr = b * b - 4 * a * c;
if(b * b - 4 * a * c < 0){
printf("YES\n");
continue;
}
if(a == 0){
if(b != 0 && c != 0){
if(c % b == 0){
printf("YES\n");
}
else{
printf("NO\n");
}
}else if(b == 0 && c == 0){
printf("NO\n");
}else{
printf("YES\n");
}
continue;
}
int q = sqrt(qr);
if(fabs(sqrt(qr) - q) < 1e-8 && (-b + q) % (2 * a) == 0 && (-b - q) % (2 * a) == 0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
Fascinated with the computer games, Gabriel even forgets to study. Now she needs to finish her homework, and there is an easy problem:
f(n)=
She is required to calculate f(n) mod 2 for each given n. Can you help her?
Multiple test cases. Each test case is an integer n(0≤n≤) in a single line.
For each test case, output the answer of f(n)mod2.
2
1
会发现奇偶性是会传递的,有规律的出现。
最后判断结果是否为3的倍数就好了,代码就不上了,是把每一位的数字加起来求和是否是三的倍数来判断的。
Hmz likes to play fireworks, especially when they are put regularly.
Now he puts some fireworks in a line. This time he put a trigger on each firework. With that trigger, each firework will explode and split into two parts per second, which means if a firework is currently in position x, then in next second one part will be in position x−1 and one in x+1. They can continue spliting without limits, as Hmz likes.
Now there are n fireworks on the number axis. Hmz wants to know after T seconds, how many fireworks are there in position w?
Input contains multiple test cases.
For each test case:
For each test case, you should output the answer MOD 1000000007.
1 2 0 2 2 2 2 2 0 3 1 2
2 3
我能想到杨辉三角加逆元求组合数,但是以前没敲过这种题目,想到了算法也凉凉。
参考博客:点击打开链接
看了大佬的代码后努力分析,写了些注释,还是觉得没全懂。
首先是求逆元,大佬博客是费马小定理求的,我自己用逆元写了个。
然后是组合数的递推推导,一层for O(nlogn)搞定组合数。
最后是特大佬的分奇偶、、不会啊,想不到啊,凉啊。。
#include
using namespace std;
typedef long long ll;
#define N 100005
ll C[N];
ll mod = 1000000007;
ll n, t, w, c, x, ans, dis, mid, idx;
/**
ll power(ll a, ll b)
{
ll tmp = 1;
while(b){
if(b & 1)
tmp = (tmp * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return tmp;
}
///费马小定理
void getc(ll t)
{
C[0] = 1;
for(int i = 1; i <= t; i++){
C[i] = (C[i - 1] * (t - i + 1) % mod * power(i, mod - 2) )% mod;
// cout << i << ' ' << C[i] << endl;
}
}
*/
void exgcd(ll a, ll b, ll & x, ll & y)
{
if(b){
exgcd(b, a % b, y, x);
y -= (a / b) * x;
}
else{
x = 1;
y = 0;
}
}
ll rev(ll a, ll m)
{
ll x, y;
exgcd(a, m, x, y);
return (x % m + m) % m;
}
void getc(ll t)
{
C[0] = 1;
for(int i = 1; i <= t; i++){
C[i] = C[i - 1] * (t - i + 1) % mod * rev(i, mod) % mod;
}
}
int main()
{
//freopen("date.txt", "r", stdin);
while(scanf("%lld%lld%lld", &n, &t, &w) != EOF){
ans = 0;
mid = (t + 1) / 2;///最底层的长度的一半
getc(t);///求逆元
for(int i = 0; i < n; i++){
scanf("%lld%lld", &x, &c);
///是所求点到原始点的距离
dis = abs(x - w);
///如果距离大于底层的长度那么怎么都炸不到。
///如果距离和t的奇偶性不同,那么刚好嵌在0里面
if(dis > t || (dis & 1) != (t & 1)) continue;
///按道理说组合数的性质从向左向右偏移都行,但是不分奇偶会WA
///我觉得好像是因为奇偶会影响mid是偏左边还是偏右边
idx = mid + ( (t & 1) ? dis / 2 : -1 * dis / 2 );
ans += c * C[idx];
ans %= mod;
}
printf("%lld\n", ans);
}
return 0;
}
/**
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
还有好多题没空一道一道过了,等基础算法学全了再说吧。