Time limit per test: 1.0 seconds
Memory limit: 256 megabytes
在进行某些桌游,例如 UNO 或者麻将的时候,常常会需要随机决定从谁开始。骰子是一种好方案。普通的骰子有六个面,分别是一点、二点、三点、四点、五点、六点,六面向上的概率相同。由于骰子只能产生六种情况,而实际桌游时,却常常有三到四人,所以,我们在掷骰子时,常常采用两颗骰子,这个「随机的选择」就由骰子向上点数之和直接决定。
我们采用这么一种方案,将向上点数之和对 p (人数)取模,模出来的 0,1,…,p−1 恰好对应 p 个人。但这并不一定是公平的。例如,如果你有算过的话,两枚普通的骰子,在四个人的情形下,就是不公平的。
所以唐纳德先生发明了一种假骰子,这种假骰子也有六个面,但六个面的点数就不再是 1,2,3,4,5,6 ,而是 a1,a2,a3,a4,a5,a6 。如果他精心选择了这六个面的点数,他仍然可以强制公平。
先给出 p 和两枚假骰子六个面的点数,问是否公平。
Input
输入具有如下形式:
pa1 a2 a3 a4 a5 a6b1 b2 b3 b4 b5 b6
第一行一个整数 p ( 3≤p≤4 )。
第二行六个整数,用空格隔开,表示第一枚骰子的点数 a1,a2,a3,a4,a5,a6 ( 1≤ai≤6 )。
第三行六个整数,用空格隔开,表示第二枚骰子的点数 b1,b2,b3,b4,b5,b6 ( 1≤bi≤6 )。
Output
如果公平输出 YES
,否则输出 NO
。
Examples
4 1 2 3 4 5 6 1 2 3 4 5 6
NO
3 1 2 3 4 5 6 6 5 4 3 2 1
YES
直接暴力模拟
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define MOD 1000000007
#define N 400010
int map1[7];
int map2[7];
int map[37];
int main()
{
int n;
while(cin>>n)
{
memset(map,0,sizeof(map));
for(int i=1;i<=6;i++)
scanf("%d",&map1[i]);
for(int i=1;i<=6;i++)
scanf("%d",&map2[i]);
for(int i=1;i<=6;i++)
{
for(int j=1;j<=6;j++)
{
map[(map1[i]+map2[j])%n]++;
}
}
int flag=1;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
if(map[i]!=map[j])
flag=0;
}
if(flag==1)
cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
Time limit per test: 1.0 seconds
Memory limit: 256 megabytes
kblack 来到了寒冬中的哈尔滨,哈尔滨的寒风令 kblack 瑟瑟发抖。
世界上最远的距离,是你与宾馆只差一条冰街,而你却忘了穿上秋裤。
kblack 终于冲进了宾馆,宾馆大厅的地板铺满了五颜六色的地砖,可以被看作是一块 n×m 格的棋盘,为了能使冻僵了的双脚尽快暖和起来,kblack 决定在地砖上走动,但是他被速冻的双脚在棋盘地板上只能走马步。
kblack 居然想知道有多少对地砖(无序点对)他可以通过若干步马步互相抵达!
Input
输入包含一行两个正整数 n , m ,表示棋盘的大小,保证 1≤n×m≤109 。
Output
输出包含一个整数,表示 kblack 可以通过马步互相到达的无序地砖对数。
Examples
1 2
0
4 2
4
其实一看数据就知道是有规律的,就是没想出来。。。
今天看了解题报告才做恍然大悟状,超过3*4的棋盘,是可以两两到达的,根据题解思路写了份代码,算是间接 A了吧
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
#define ll long long
#define MOD 1000000007
#define N 100010
int dx[]={-2,-1,1,2};
int dy[]={1,2,2,1};
int n,m;
ll gcd(ll a,ll b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int judge(int x,int y)
{
if(x<=n&&x>=1&&y>=1&&y<=m)
return 1;
return 0;
}
ll CC(int n,int m)
{
ll ans=1;
if(n<m)
return 0;
else if(n==m)
return 1;
int j=2;
ll temp=1;
int a=max(m,n-m);
int b=min(m,n-m);
for(int i=n;i>a;i--)
{
ans*=i;
if(j<=b||temp>1)
{
if (j<=b)
temp*=j;
if (temp>1)
{
ll GCD=gcd(ans,temp);
ans/=GCD;
temp/=GCD;
}
}
j++;
}
return ans;
}
int main()
{
while(cin>>n>>m)
{
/*if(min(n,m)<2)
{
cout<<0<<endl;
continue;
}
ans=0;
for(int j=1;j<m;j++)
{
for(int i=1;i<=n;i++)
{
//cout<<"i j "<<i<<" "<<j<<endl;
dfs(i,j,0);
}
}*/
if(min(n,m)==1)
cout<<0<<endl;
else if(max(n,m)==2)
cout<<0<<endl;
else if(n==3&&m==3)
cout<<CC(8,2)<<endl;
else if(m==2)
cout<<2*CC(n/2,2)+2*CC(n-n/2,2)<<endl;
else if(n==2)
cout<<2*CC(m/2,2)+2*CC(m-m/2,2)<<endl;
else if(m*n>=3*4)
cout<<CC(n*m,2)<<endl;
}
Time limit per test: 2.0 seconds
Memory limit: 256 megabytes
易位构词 (anagram),指将一个单词中的字母重新排列,原单词中的每个字母都出现有且仅有一次。例如 "unce" 可以被易位构词成 "ecnu"。在某些情况下,要求重排而成的依然是一个单词,但本题没有这种要求,因为我们根本没有词典。
我们所感兴趣的是,有些单词中的字母进行适当的重排后,可以使得构成的单词每个对应的位置上字母都不一样。例如 "unce" 和 "ecnu",就有 "u" ≠ "e", "n" ≠ "c", "c" ≠ "n", "e" ≠ "u"。现在给出一个单词,问是否存在这样一个重排。
Input
一行一个单词 s ( 1≤|s|≤105 )。单词完全由 26 个小写英文字母构成。
Output
输出一个单词。如果有多解,输出任意解。如果不存在,输出 impossible
。
Examples
unce
ecnu
aaaaaa
impossible
显然最多的字母出现次数大于一半的情况是不行的。否则就将每个字母的位置和字母绑定一下,
按字母序对结构体进行排序。然后右移「出现最多的字母出现次数」位,再排回来就可以了
还一个字符串水题水过了easy的(暴力查找子串),hard一直超时,不发了#include<iostream> #include<stdio.h> #include<string.h> #include<cmath> #include<string> #include<algorithm> using namespace std; #define ll long long #define MOD 1000000007 #define N 100005 int num[256]; char s[N],temp[N]; char ans[N]; struct node { char c; int p; }map[N]; bool cmp(node a,node b) { return num[a.c]>num[b.c]||(num[a.c]==num[b.c]&&a.c<b.c); } int main() { scanf("%s",s); int len=strlen(s); int ma=0; for(int i=0;i<len;i++) { map[i].c=s[i]; map[i].p=i; num[s[i]]++; if(num[s[i]]>ma) ma=num[s[i]]; } sort(map,map+len,cmp); if((ma*2)>len) cout<<"impossible"<<endl; else { for(int i=0;i<len;i++) temp[(i+ma)%len]=map[i].c; for(int i=0;i<len;i++) ans[map[i].p]=temp[i]; cout<<ans<<endl; } return 0; }