A.Puzzle Pieces
没啥好说的,画着画着就出来了。
P.S. 差点忘了关文件重定向(汗)
#include <iostream>
#include <map>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod
ll ans=1;
while(n){
if(n&1) ans=(ans*a);
a=a*a;
n>>=1;
}
return ans;
}
//==============================================================
int t,n,m;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//===========================================================
read(t);
while(t--){
read(n),read(m);
int flag=0;
if(n==1||m==1){
flag=1;
}
else if(n<=2&&m<=2){
flag=1;
}
if(flag){
puts("YES");
}
else{
puts("NO");
}
}
//===========================================================
return 0;
}
B.Card Constructions
容易想到这里面是有数学关系的。题目要求是:每次构建最高的三角形,然后剩下的继续构建,问一共能建多少个,还是能想得到打表的。
至于数学关系,我是这么推导的:
对于一个高度为h的大三角形,它的小三角形块的数量是
(
1
+
h
)
∗
h
/
2
(1+h)*h/2
(1+h)∗h/2,每个三角形需要3张卡,而且最底层没有卡,且缺少了h张卡,因此,高度为h的大三角形所需卡片数量为
(
1
+
h
)
∗
h
/
2
∗
3
−
h
=
(
h
+
3
∗
h
∗
h
)
/
2
(1+h)*h/2*3-h=(h+3*h*h)/2
(1+h)∗h/2∗3−h=(h+3∗h∗h)/2。剩下的就是打表加二分了。
P.S. 我个憨批,打表总是打漏一个极限情况,以后不能再犯了昂
#include <iostream>
#include <map>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
int t;
const int maxn=1e9+100;
vector<ll> list1;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//===========================================================
read(t);
list1.push_back(0);
for(register int i=1;;i++){
list1.push_back((i+3*i*i)/2);
if(((i+3*i*i)/2)>maxn){//记得多打一个极限情况!!!!!!!!!!!!!!!!!!
break;
}
}
while(t--){
int n;
read(n);
ll cnt=0;
register ll hh=lower_bound(list1.begin(),list1.end(),n)-list1.begin();
while(n){
if(hh==0){
break;
}
while(list1[hh]>n){
hh--;
}
if(hh==0){
break;
}
n-=list1[hh];
cnt++;
}
write(cnt);
putchar('\n');
}
//===========================================================
return 0;
}
C.Hilbert’s Hotel
虽然比赛的时候有感觉,但是没有想到比较好的证明,最后还是没有交上去,有点遗憾。。。
题目也比较难读,大概的意思是:对于任意一个数k,经过变换为
k
+
a
k
%
n
k+a_{k\%n}
k+ak%n之后生成的所有结果,能不能够不重叠。说的简单点,就是能不能够通过一个类似于函数的变换,把数轴映射成另一个数轴。
看了大佬的证明是这样的:
若存在重复,则存在:
i
+
a
i
%
n
=
j
+
a
j
%
n
(
m
o
d
n
)
i+a_{i\%n}=j+a_{j\%n}(modn)
i+ai%n=j+aj%n(modn)。所以,我们只需要验证在0~n-1范围内是否有符合上式的i和j存在,这里有点鸽巢原理的味道:若符合条件则从0验证到n-1,映射出来的结果应该是铺满整个0到n-1的区间,我们mod n的意义就是把这些数都集中到这个区间来的。所以,建个map记录下就行了。
#include <iostream>
#include <map>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
const int maxn=2e5+10;
int t,n;
ll a[maxn];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//===========================================================
read(t);
while(t--){
map<int,int> cnt;
cnt.clear();
read(n);
rep(i,0,n-1) read(a[i]);
int flag=0;
rep(i,0,n-1){
cnt[((i+a[i%n])%n+n)%n]++;
if(cnt[((i+a[i%n])%n+n)%n]>=2){
flag=1;
break;
}
}
if(flag){
puts("NO");
}
else{
puts("YES");
}
}
//===========================================================
return 0;
}