A. Music
题意:
一首歌长度为S秒,已经下载了T秒,下载速度为每q秒的现实时间能下载下来(q-1)秒 的歌曲。现在开始听歌,如果听到还没下载的地方就从0秒的地方开始replay,求一首歌听完需要从0秒听几次(包括一开始那次)
思路:
我们可以用路程-时间的思路来考虑这道题。
假设两位选手“播放”与“下载”,“播放”的起点是0m处,“下载”的起点是Tm处,终点在Sm处,“播放”的速度是1m/s,“下载”的速度是(q-1)/q m/s。
假设两名选手在Xm处相遇,那么:
(X-T) / ((q-1)/q)= (X-0)/1
转化下就可得到X = qT。
那么第qT秒就是第一次需要replay的地方。replay以后,T = X,继续计算qT,直到qT > S,累计replay的次数即可。
代码:
/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
using namespace std;
#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;
int main(){
// freopen("input.txt","r",stdin);
int t,s,q;
while(cin >> t >> s >> q){
int ans = 1;
int x = s*q;
while(x < t){
ans++;
x = x*q;
}
cout << ans << endl;
}
return 0;
}
B - Inventory
题意:
把n个数组成的数列变成由1~n组成的数列,1~n每个数只能且必须出现一次。
思路:
map累计每个元素出现次数,再从头扫一遍,出现次数大于1的元素更换为出现次数为0的元素,更新map。
统计下,缺谁补谁呗
代码:
/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
using namespace std;
#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;
map<int,int>mp;
vector<int>q;
int a[100005];
int main(){
// freopen("input.txt","r",stdin);
int n;
while(cin >> n){
mp.clear();
q.clear();
cls(a);
for(int i = 1 ; i <= n ; i++){
int tmp;
scanf("%d",&tmp);
mp[tmp]++;
a[i] = tmp;
}
for(int i = 1 ; i <= n ; i++){
if(mp[i] < 1) {
q.pb(i);
}
}
int k = 0;
for(int i = 1 ; i <= n ; i++){
if(mp[a[i]] >= 2 || a[i] > n){
mp[a[i]]--;
a[i] = q[k++];
}
}
for(int i = 1 ; i < n ; i++){
printf("%d ",a[i]);
}
printf("%d\n",a[n]);
}
return 0;
}
C - Primes or Palindromes?
题意:
定义π(n) = 不大于n的素数个数,
定义rub(n) = 不大于n的回文数个数,
输入p,q(1/42 <= p/q <= 42),求满足π(n) <= p/q * rub(n)的n的最大值。
思路:
你只需要知道,π(n) 的增长速度大于rub(n),打个表看看什么时候π(n) > 42* rub(n),发现大概是n = 2*10^6的时候,再加上3s的时限与cf超越各大oj的机器性能。
枚举大法好。
代码:
/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
using namespace std;
#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;
const int maxn = 10000000+5;
bool notPrime[maxn+5];
void Prime(void){
memset(notPrime,false,sizeof(notPrime));
for(int i = 2; i*i <= maxn; i++){
if(!notPrime[i]){
for(int j = i*i; j <= maxn; j += i){
notPrime[j] = true;
}
}
}
}
int reverse(int n) {
int res = 0;
while(n){
int d = n % 10;
res = res*10 + d;
n /= 10;
}
return res;
}
bool hui(int n){
if(reverse(n) == n) return true;
return false;
}
vector<int>v;
int main(){
//freopen("output.txt","w+",stdout);
int p,q;
cin >> p >> q;
Prime();
lint pr = 0,hu=0;
v.clear();
v.pb(1);
for(int i = 1 ; i <= 10000000; i++){
if(!notPrime[i] && i!= 1){
pr++;
}
if(hui(i)){
hu++;
}
if(pr * q <= hu*p){
v.pb(i);
}
}
if(v.size() >= 1){
cout <<v[v.size()-1] <<endl;
return 0;
}
cout << "Palindromic tree is better than splay tree" << endl;
return 0;
}
D - Symmetric and Transitive
题意:
求1到n的n个元素组成的二元关系集合中,满足对称性和传递性但不满足自反性的二元组关系集合的个数。
思路:
赛后看到这个题(手速过慢比赛的时候没来得及看),觉得自己的离散数学知识都喂队友了。。
Bell number,又名贝尔数,表示基数为n的集合划分数目,也表示n元素集合的等价关系的数目,于是我们可以发现ans[n] = Bell[n+1] - Bell[n],从下一个等价关系个数中减去从当前等价关系个数,即为当前不满足自反的二元组关系个数。
贝尔数的推导可以用贝尔三角形或第二类斯特林数和。
这个题重在题意理解和样例理解上:
样例1:ρ = ∅
样例2:ρ = ∅ , ρ = {(x, x)} , ρ = {(y, y)}.
样例3:
0个元素(空集):
ρ = ∅;
1个元素:
ρ= {(x, x)},ρ= {(y, y)},ρ= {(z, z)};
2个元素:
ρ= {(x, x), (y, y)},ρ= {(x, x), (z, z)},ρ= {(y, y), (z, z)};
3个元素:
无;
4个元素:
ρ= {(x, x), (y, y), (x, y), (y, x)},ρ= {(y, y), (z, z), (y, z), (c, y)},ρ= {(x, x), (z, z), (x, z), (z, x)}
5、6个元素:无
一共10个。
/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
using namespace std;
#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;
const int mod = 1e9+7;
const int maxn = 4000 + 5;
lint B[maxn][maxn];
//注释语句可以打印bell三角形
void init(){
B[1][1] = 1;
//cout << 1 <<endl;
for(int i = 2 ; i <= 4001; i++){
B[i][1] = B[i-1][i-1];
//cout << B[i][1] << ' ';
for(int j = 2 ; j <= i ; j++){
B[i][j] = (B[i-1][j-1] + B[i][j-1]) % mod;
//cout << B[i][j] <<' ';
}
}
}
int main(){
init();
int n;
while(cin >> n)
cout << B[n+1][n] % mod << endl;
return 0;
}