1.字符游戏
(moo.pas/c/cpp)
【问题描述】
小x和同学们喜欢玩一种游戏叫 "Moo".
他们总是站在一排,然后依次说出相应的一个字符,如果出错的同学,就要受到惩罚。
下面就是这个游戏的一个序列:
m o o m o o o m o o m o o o o m o o m o o o m o o m o o o o o
这个游戏的序列最初状态是 S(0) "m o o",也就是初始状态只有3个字符;如果要查询的字符超过3个,就要产生下一个字符序列,产生序列的规则如下:
s(k)是 s(k-1) + "m o ... o"(k+2)个'o' +s(k-1)
下面是相应的序列
S(0) = "m o o"
S(1) = "m o o m o o o m o o"
S(2) = "m o o m o o o m o o m o o o o m o o m o o o m o o"
注意:如果游戏的序列长度不够,就按照以上规则继续往下产生就可以了,所以游戏用的序列是无穷大的。
那么现在问题就出来了:
游戏中第x个人需要说的字符是什么呢?当然只有可能是 'm'或'o'.
本题有m(m<=10)个提问,每个提问给一个整数x,你要回答第x个人需要说出的字符数。
【输入】
第一行一个整数m(m<=10)
接下来m行,每行一个整数x (1 <=x <= 10^9)
【输出】
m行,每行一个字符,第i个人需要说的字符。
【输入输出样例1】
moo.in |
moo.out |
2 1 11 |
m m |
【数据范围】
如题目描述。保证会有部分小数据查询位置在200以内。
辣鸡不会写QAQ
正解:递归,判断三部分。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int m,len[40],x; char solve(int k,int i) { if(k>len[i]) return solve(k,i+1); if(k<len[i-1]) return solve(k,i-1); if(k>len[i-1]) k-=len[i-1]; if(k==1) return 'm'; if(k<i+3) return 'o'; k=k-i-3; return solve(k,i-1); } int main(){ cin>>m; len[0]=3; for(int i=1;i<=40;i++) len[i]=len[i-1]*2+i+3; for(int i=1;i<=m;i++) { cin>>x; cout<<solve(x,0)<<endl; } return 0; }
1.暑假作业
(mtime.pas/c/cpp)
【问题描述】
暑假作业是必须要写的,越到假期结束前,写作业的效率就越高,小x就面临这个问题。
现在小x有n个作业要完成。(1 <= N <= 1,000)并且每个作业有两个属性:Ti和Si.Ti表示第i项作业需要Ti的时间来完成,Si表示最迟必须Si时刻完成第i项作业。
现在假设开始时刻为0,而小x想知道最晚什么时候开始写作业,可以把作业完成,这样他可以知道自己可以浮躁的时间。
【输入】
第一行一个整数 N。
接下来N行,每行两个整数T_i (1 <= T_i <= 1,000)和 S_i(1 <= S_i <= 1,000,000)。
【输出】
一个整数,表示小x最晚开始写作业的时刻,如果根本完成不了,输出-1.
【输入输出样例】
mtime.in |
mtime.out |
4 3 5 8 14 5 20 1 16 |
2 |
小x最晚2时刻开始工作,在5时刻完成第一个作业,之后,在14时刻完成第2项作业,在15时刻完成第4项作业,之后在20时刻完成第3项作业。
【数据范围】
30% n<=100
50% n<=500
100% 如 题目描述
应该以时间最后的优先啦,用布尔标记从时间最后找最佳完成时间,再向前标记。
由于时间最后为优先,所以只要确定最后完成时,前面就一定没有被标记。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,b=0,f[1000010]; struct qaq { int t,s; }a[1010]; bool mycmp(qaq x,qaq y) { return (x.s>y.s); } int main() { freopen("mtime.in","r",stdin); freopen("mtime.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) cin>>a[i].t>>a[i].s; sort(a,a+n+1,mycmp); for(int i=1;i<=n;i++) { for(int j=a[i].s;j>=0;j--) { if(f[j]==0) {b=j; break;} if(j==0&&f[j]==1) {cout<<-1<<endl; return 0;} } for(int j=b;j>b-a[i].t;j--) { f[j]=1; if(j==0) {cout<<-1<<endl; return 0;} } } for(int i=1;i<=a[1].s;i++) if(f[i]==1) { cout<<i-1<<endl; break; } return 0; }
1.福星
(pathhead.pas/c/cpp)
【问题描述】
小x的数学兼体育老师发明了一个很无聊的游戏。
在体育课上,让小x和他的同学们一共N (1 <= N <= 100,000)个人,每个人抽取一个幸运号码A_i (1 <= A_i <= 1,000,000)。
如果第i个人的幸运号码能被第j个人的幸运号码整除,那么第j个人就是第i个人的福星。自己当然不能是自己的福星。
现在小x的数学兼体育老师想让小x算出,每个人都有多少个福星。
【输入】
第一行一个整数N。
接下来N行,每行一个整数A_i,表示每个人的幸运号码
【输出】
N行,每行一个整数,表示每个人的福星个数。
【输入输出样例】
pathhead.in |
pathhead.out |
5 2 1 2 3 4 |
2 0 2 1 3 |
【数据范围】
一共有13组数据
4组数据 n<=100 A_i<=200
6组数据 n<=5000 A_i <=50000
其余如题目描述
只会打暴力,没救了。
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; int n,a[100010],s[100010]; int main(){ freopen("pathhead.in","r",stdin); freopen("pathhead.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j){ if(a[i]==a[j]) s[i]++; if(a[i]>a[j]&&a[i]%a[j]==0) s[i]++; } for(int i=1;i<=n;i++) cout<<s[i]<<endl; return 0; }
正解:筛法,找每个数有几个,然后往他们的倍数上加他们,他们的倍数一定整除以他们,有多少个他们,他们的倍数就有多少个福星。->好绕啊。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; int n,maxx=0,a[1001000],ans[1001000],num[1001000]; int main(){ cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; num[a[i]]++; maxx=max(maxx,a[i]); } for(int i=1;i<=maxx;i++) { if(num[i]>0) for(int j=i;j<=maxx;j+=i) ans[j]+=num[i]; } for(int i=1;i<=n;i++) cout<<ans[a[i]]-1<<endl; return 0; }
骰子游戏 pogo
题目描述:
小x在玩一个骰子游戏。
这个骰子有6个面,如图所示:相对的两个面的值的累加和是7,数字1相对的面是数字6,2对着5,3对着4.
现在,有一个r行,c列的表格,骰子在表格最左上角,数字1朝上,数字3在1的右边。
现在小x按照以下规则进行移动:
1:他先把骰子从第一行的第一列,向右依次滚到最右边那列。
2:他把骰子向下滚到下一行。
3:他把骰子从右依次滚到最左边那列。
4:依次类推,他又把骰子滚到下一行,并按照第一步那样依次滚动
小x依次的重复以上步骤,直到把所有的格子都滚一遍。
在滚到每个格子的时候,小x都会记录朝上那面的格子的数字。
现在小x要考验一下你,所有数字的和是多少?
输入格式:
两个用空格隔开的整数r和c(1 ≤ r,c ≤ 100 000), 表示题目描述的表格的行和列。
输出格式:一个整数,如题目描述的所有朝上那面数字的累加和。
样例1:输入 |
样例2:输入 |
样例3:输入 |
3 2 |
3 4 |
737 296 |
样例1:输出 |
样例2:输出 |
样例3:输出 |
19 |
42 |
763532 |
50%数据保证 r和c小于等于100
纯模拟,模拟一下就ok,不过模拟要死。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; long long ans=0,m,n; int main() { freopen("pogo.in","r",stdin); freopen("pogo.out","w",stdout); cin>>n>>m; int t=m/4; for(int i=1;i<=n;i++) ans+=t*14; if(m%4==1) { ans+=(n/4)*14; if(n%4==1) ans+=1; if(n%4==2) ans+=6; if(n%4==3) ans+=12; } if(m%4==2) { ans+=(n/6)*42; if(n%6==1) ans+=5; if(n%6==2) ans+=11; if(n%6==3) ans+=19; if(n%6==4) ans+=28; if(n%6==5) ans+=36; } if(m%4==3) { ans+=(n/2)*22; if(n%2==1) ans+=11; } cout<<ans; return 0; }