SRM144 - SRM 148(少144-DIV1-LV3,147-DIV2-LV3)
SRM 144
DIV 1 500pt
tag:组合
题意:彩票中奖。给定n, m,从1-n中选择m个数组成数列a1, a2, a3...am。对于数列{am}分别满足以下条件的概率:
(1)数列所有元素不相同且非严格递增;
(2)数列元素可以相同,可以递减;
(3)数列元素不相同,可以递减;
(4)数列元素可以相同,且非严格递增。
解法:所有四种情况均可以用排列组合公式直接解决,要用大数。最难的是最后一种情况,我也是最后一种情况公式写错了。
并且,最后一种情况公式的推导过程也可以看一看官方题解,是一种以前从来没用过的思考方法。
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define rep(i, n) for(long long i = 0; i < (n); i ++)
#define repf(i, a, b) for(long long i = (a); i <= (b); i ++)
#define repd(i, a, b) for(long long i = (a); i >= (b); i --)
#define flin freopen( "a.in" , "r" , stdin )
#define flout freopen( "a.out" , "w" , stdout )
#define out(x) cout<<#x<<':'<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false)
#define flag fla typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef unsigned long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;} class Node{
public:
string name;
int64 num;
}node[]; bool cmp( Node x , Node y )
{
if( x.num < y.num )
return true;
else if( x.num == y.num && x.name < y.name )
return true;
return false;
} int64 MyPow( int64 p , int64 n )
{
int64 sq = ;
while( n > ){
if( n % )
sq = sq * p;
n /= ;
p = p * p;
}
return sq;
} int64 C( int64 x , int64 y )
{
int64 ans = ;
for( int64 i = y , j = ; i > y-x ; i-- , j ++ )
ans = (ans*i) / j;
return ans;
} int64 A( int64 x , int64 y )
{
int64 ans = C(x,y);
repd( i , x , )
ans *= i;
return ans;
} int64 Ask_Num( int a , int b , bool c , bool d )
{
int64 ret;
if( c && d )
ret = C(b,a);
if( c && !d ){
//ret = MyPow(a,b) - C(b,a); /*Think : Why Wrong by this way?*/
/*很好的组合问题,以下代码公式为C(b,a+b-1)Think why*/
ret = ;
for( int64 i = ; i < b ; i ++ )
ret *= ( a + b - i - );
for( int64 i = ; i < b ; i ++ )
ret /= ( i + );
/* end */
}
if( !c && d )
ret = A(b,a);
if( !c && !d )
ret = MyPow(a,b);
return ret;
} class Lottery
{
public:
vector <string> sortByOdds(vector <string> rules){
int n = SZ( rules );
rep( i , n ){
node[i].name.clear();
string s = rules[i];
int len = SZ(s);
int flag;
rep( j , len ){
if( s[j] == ':' ){
flag = j;
break;
}
node[i].name.PB(s[j]);
}
flag += ;
int a = ( s[flag] - '' ) * + s[flag+] - '';
flag += ;
if( s[flag] != ' ' )
a = a * + s[flag++] - '';
flag ++;
int b;
b = s[flag] - '';
flag += ;
bool c = ( s[flag] == 'T' );
flag += ;
bool d = ( s[flag] == 'T' );
node[i].num = Ask_Num( a , b , c , d );
}
sort( node , node+n , cmp );
VS anss;
anss.clear();
rep( i , n )
anss.PB( node[i].name );
return (anss);
}
//by plum rain
};
DIV 1 1100pt
tag:没做,似乎图论
SRM 145
DIV 2 1100pt, DIV 1 600pt
tag: 模拟
// BEGIN CUT HERE
/* */
// END CUT HERE
#line 7 "VendingMachine.cpp"
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define rep(i, n) for(long long i = 0; i < (n); i ++)
#define repf(i, a, b) for(long long i = (a); i <= (b); i ++)
#define repd(i, a, b) for(long long i = (a); i >= (b); i --)
#define flin freopen( "a.in" , "r" , stdin )
#define flout freopen( "a.out" , "w" , stdout )
#define out(x) cout<<#x<<':'<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;}
inline void swa(int &a, int &b) {int t = a;a = b;b = t;}
struct PUR{
int c, s;
int time;
}bn[]; int an[][];
int cn[];
int snum, cnum, pnum; int rot(int a, int b)
{
if (a > b)
swa(a, b);
return min (b-a, cnum-b+a);
} int find_max()
{
int tmp = , ret = ;
rep (i, cnum)
if (tmp < cn[i]){
tmp = cn[i];
ret = i;
}
return ret;
} int solve()
{
int ret = ;
CLR(cn);
rep (i, cnum)
rep (j, snum)
cn[i] += an[j][i];
int flag = find_max();
ret += rot (, flag);
rep (i, pnum){
int s = bn[i].s, c = bn[i].c, tim = bn[i].time;
if (an[s][c] == )
return -;
cn[c] -= an[s][c];
an[s][c] = ;
ret += rot (c, flag);
flag = c;
if (i < pnum- && bn[i+].time - tim >= ){
int pos = flag;
flag = find_max();
ret += rot (flag, pos);
}
}
int pos = flag;
flag = find_max();
ret += rot (pos, flag);
return ret;
} class VendingMachine
{
public:
int motorUse(vector <string> prices, vector <string> purchases){
/*data initial*/
CLR(an);
snum = SZ(prices);
int a = , pos = ;
rep (i, snum){
string s = prices[i];
int size = SZ(s);
rep (j, size){
if (s[j] == ' '){
an[i][pos++] = a;
a = ;
continue;
}
a = a * + s[j] - '';
}
an[i][pos++] = a;
cnum = pos;
a = ;
pos = ;
}
cout << endl;
pnum = SZ(purchases);
rep (i, pnum){
int a = ;
string s = purchases[i];
int j = ;
while (s[j] != ','){
a = a * + s[j] - '';
j ++;
}
bn[i].s = a;
a = ; j ++;
while (s[j] != ':'){
a = a * + s[j] - '';
j ++;
}
bn[i].c = a;
a = ; j ++;
while (j < SZ(s)){
a = a * + s[j] - '';
j ++;
}
bn[i].time = a;
}
/*end initial*/
return (solve());
}
//by plum rain
};
DIV 1 1000pt
tag:dp
题意:爬山,从高度为0处爬高度为h的山,当前高度为k时,经过一步可以爬到k-1, k, k+1处。给定数字h, n, 数组{an},求满足以下条件的爬山方法种数:
(1)爬山过程中,必须到达过至少一次高度h处
(2)从高度0处开始爬山,并且最终回到高度0处,中途不能到高度0处
(3)总共走了n步
(4)如果将每一步到达的高度依次计入一个数组,比如从0爬到1再回到0计为数组{0, 1, 0},则{an}是它的一个子集。
解法:dp,比较普通,没什么好说的。感觉作为一道div1 lv3的题,并不难,只是情况比较复杂,我开了4维数组,写了两遍代码。
还是代码功底太弱了.....
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define rep(i, n) for(int i = 0; i < (n); i ++)
#define repf(i, a, b) for(int i = (a); i <= (b); i ++)
#define repd(i, a, b) for(int i = (a); i >= (b); i --)
#define flin freopen( "a.in" , "r" , stdin )
#define flout freopen( "a.out" , "w" , stdout )
#define out(x) cout<<#x<<':'<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;} int d, m, n;
int64 dp[][][][]; void DP(VI landmarks)
{
rep (i, d+){
rep (k, n+)
rep (l, )
dp[i][][k][l] = ;
}
dp[][][][] = ;
repf (i, , d){
if (i == d){
dp[i][][n][] = dp[i-][][n][];
break;
}
repf (j, , m){
repf (k, , n){
if (j < m){
rep (l, ){
dp[i][j][k][l] = dp[i-][j][k][l] + dp[i-][j-][k][l] + dp[i-][j+][k][l];
if (k && j == landmarks[k-])
dp[i][j][k][l] = dp[i-][j][k-][l] + dp[i-][j-][k-][l] + dp[i-][j+][k-][l];
}
}
else{
dp[i][j][k][] = ;
dp[i][j][k][] = dp[i-][j][k][] + dp[i-][j-][k][] + dp[i-][j][k][] + dp[i-][j-][k][];
if (k && j == landmarks[k-])
dp[i][j][k][] = dp[i-][j][k-][] + dp[i-][j-][k-][] + dp[i-][j][k-][] + dp[i-][j-][k-][];
}
}
}
}
tst(aaa);
rep (i, d+){
out (i);
rep (j, m+){
rep (k, n+)
cout << dp[i][j][k][] << " " << dp[i][j][k][] << " ";
cout << endl;
}
cout << endl << endl;
}
} class HillHike
{
public:
long long numPaths(int distance, int maxHeight, vector <int> landmarks){
d = distance; m = maxHeight; n = SZ(landmarks);
DP(landmarks);
return (dp[d][][n][]);
}
//by plum rain
};
SRM 146
DIV 1 300pt, DIV 2 500pt
tag:计数问题,math
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <string>
#include <utility>
#include <map>
#include <ctime>
#include <stack> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define rep(i, n) for(int i = 0; i < (n); i ++)
#define repf(i, a, b) for(int i = (a); i <= (b); i ++)
#define repd(i, a, b) for(int i = (a); i >= (b); i --)
#define flin freopen( "a.in" , "r" , stdin )
#define flout freopen( "a.out" , "w" , stdout )
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;} int64 ask_sqa(int64 n, int64 m)
{
int64 ret = ;
int a = ;
while (a <= m){
ret += (n-a+) * (m-a+);
a ++;
}
return ret;
} class RectangularGrid
{
public:
long long countRectangles(int width, int height){
int64 n = width, m = height;
if (n < m)
swap (n, m);
int64 tot = ((n * (n + )) / ) * m * (m + ) / ;
int64 sqa = ask_sqa(n, m);
return (tot - sqa);
} };
DIV 1 600 pt
tag:dfs
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <string>
#include <utility>
#include <map>
#include <ctime>
#include <stack> using namespace std; #define CLR(x) memset(x, true, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define rep(i, n) for(int i = 0; i < (n); i ++)
#define repf(i, a, b) for(int i = (a); i <= (b); i ++)
#define repd(i, a, b) for(int i = (a); i >= (b); i --)
#define flin freopen( "a.in" , "r" , stdin )
#define flout freopen( "a.out" , "w" , stdout )
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ;
const int maxx = ;
const int le = ;
const int ri = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;} struct po{
bool hash[ri+];
}; int n;
bool ans[ri+];
VS gg, rr; bool can_apr(int num)
{
rep (i, ){
if (!((num%) < ) || !(num%))
return false;
num /= ;
}
return true;
} bool match (int num, int pos)
{
if (!can_apr(num))
return false;
int b = , w = ;
string g = gg[pos], r = rr[pos];
int a[];
a[] = num % ; num = (num - a[]) / ;
a[] = num % ; num = (num - a[]) / ;
a[] = num % ; num = (num - a[]) / ;
a[] = num % ;
rep (i, ){
if (a[i]+'' == g[i]){
b ++;
a[i] = -;
g[i] = ;
}
}
rep (i, ){
rep (j, )
if (a[j]+'' == g[i]){
w ++;
a[j] = -;
g[i] = ;
break;
}
}
if (b+'' != r[] || w+'' != r[])
return false;
return true;
} void DFS(int pos, bool x, po p)
{
if (pos == n){
if (x)
repf (i, le, ri)
ans[i] = (ans[i] || p.hash[i]);
return;
}
po tmp = p;
repf (i, le, ri){
if (i == && pos == && x){
out (tmp.hash[]);
out (match (i, pos));
}
if (tmp.hash[i] && !match (i, pos))
tmp.hash[i] = false;
}
if (!pos)
out (tmp.hash[]);
if (pos == && !x)
out (tmp.hash[]);
if (pos == && x)
out (tmp.hash[]);
DFS(pos+, x, tmp);
if (!x){
tmp = p;
bool xxx[ri+];
CLR (xxx);
repf (i, le, ri){
if (xxx[i] && !match (i, pos))
xxx[i] = false;
}
repf (i, le, ri)
tmp.hash[i] = (tmp.hash[i] && !xxx[i]);
DFS (pos+, , tmp);
}
} class Masterbrain
{
public:
int possibleSecrets(vector <string> guesses, vector <string> results){
n = SZ (guesses);
gg.clear(); rr.clear();
gg = guesses; rr = results;
po p;
CLR (p.hash);
memset (ans, , sizeof(ans));
DFS (, , p);
int ret = ;
repf (i, le, ri){
if (can_apr(i) && ans[i]){
ret ++;
cout << i << endl;
}
}
return (ret);
}
};
DIV 2 1000pt
tag:记忆划搜索
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <string>
#include <utility>
#include <map>
#include <ctime>
#include <stack> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define rep(i, n) for(int i = 0; i < (n); i ++)
#define repf(i, a, b) for(int i = (a); i <= (b); i ++)
#define repd(i, a, b) for(int i = (a); i >= (b); i --)
#define flin freopen( "a.in" , "r" , stdin )
#define flout freopen( "a.out" , "w" , stdout )
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ;
const int N = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;} int an[<<N];
int n;
VI t; int Search (int now, int left)
{
if (left == ){
an[now] = ;
return an[now];
}
if (an[now])
return an[now];
int tmp = maxint;
rep (i, n){
rep (j, n){
if (i == j)
continue;
if ((now>>i) & && (now>>j) & ){
if (left == ){
tmp = max (t[i], t[j]);
break;
}
now -= ((<<i) + (<<j));
rep (k, n){
if (!((now>>k) & )){
now += (<<k);
tmp = min (tmp, Search(now, left-) + max (t[i], t[j]) + t[k]);
now -= (<<k);
}
}
now += ((<<i) + (<<j));
}
}
}
an[now] = tmp;
return an[now];
}
class BridgeCrossing
{
public:
int minTime(vector <int> times){
n = SZ (times);
if (n == )
return times[];
if (n == )
return max (times[], times[]);
t.clear();
rep (i, n)
t.PB(times[i]);
sort (t.begin(), t.end());
int ma = ( << n) - ;
CLR(an);
Search (ma, n);
return (Search(ma, n));
}
};
DIV 1 800pt
tag: 模拟
Ps:800pt 的 lv3....
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <string>
#include <utility>
#include <map>
#include <ctime>
#include <stack> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define rep(i, n) for(int i = 0; i < (n); i ++)
#define repf(i, a, b) for(int i = (a); i <= (b); i ++)
#define repd(i, a, b) for(int i = (a); i >= (b); i --)
#define flin freopen( "a.in" , "r" , stdin )
#define flout freopen( "a.out" , "w" , stdout )
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;} char a[];
string s[];
bool stp[];
int tim = maxint; bool match(int i, char x)
{
if (i == && x == 'N')
return true;
if (i == && x == 'E')
return true;
if (i == && x == 'S')
return true;
if (i == && x == 'W')
return true;
return false;
} bool ok()
{
for (int i = ; i < ; i ++){
if (a[i])
return false;
if (!(SZ(s[i]) == && s[i][] == '-'))
return false;
}
return true;
} void lesss(int x)
{
int len = SZ (s[x]);
for (int i = ; i < len; i ++){
if (s[x][i] == '-'){
s[x].erase(i, );
break;
}
}
if (!SZ(s[x]))
s[x].PB ('-');
} void car_in()
{
for (int i = ; i < ; i ++){
if (stp[i]) lesss(i);
else{
if (s[i][] == '-') lesss(i);
else{
a[i] = s[i][];
s[i].erase(s[i].begin());
if (!SZ (s[i]))
s[i].PB('-');
}
} }
} void car_go()
{
for (int i = ; i < ; i ++)
if (match(i, a[i])) a[i] = ;
char x = a[];
for (int i = ; i < ; i ++)
a[i] = a[i+];
a[] = x;
} bool stop(int x)
{
if (s[][] !='-' && s[][] != '-' && s[][] != '-' && s[][] != '-'){
if (x) return true;
if (!a[]) return false;
return true;
}
if (s[(x+)%][] == '-' && !a[(x+)%])
return false;
return true;
} string clr(string x)
{
int len = SZ(x);
int flag = -;
for (int i = ; i < len; i ++){
if (x[i] == '-') continue;
flag = i;
}
x.erase (flag+, len-flag-);
if (!SZ(x)) x.PB('-');
return x;
} class Roundabout
{
public:
int clearUpTime(string north, string east, string south, string west){
tim = maxint;
CLR(a);
CLR(stp);
s[].clear(); s[].clear(); s[].clear(); s[].clear();
s[] = clr(north);
s[] = clr(east);
s[] = clr(south);
s[] = clr(west);
for (int i = ; i < ; i ++ )
if (stop (i)) stp[i] = ;
tim = ;
if (ok())
return tim;
while (){
tim ++;
car_go();
car_in();
for (int i = ; i < ; i ++){
if (stop(i)) stp[i] = ;
else stp[i] = ;
}
if (ok())
break;
}
return (tim);
}
};
SRM 147
DIV 2 1000pt
tag:没做,看不懂题,让Jne帮忙看也没看懂
DIV 1 500pt
tag:模拟
Ps:代码写的太复杂了- -,up面和down面数目相同,front面和back面相同,left面和right面相同,则样代码就可以简化很多了- -。这就是没有仔细手算样例的后果- -
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <string>
#include <utility>
#include <map>
#include <ctime>
#include <stack> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;} struct fra{
int64 a, b;
// a / b
void clr(){
a = ; b = ;
}
};
vector<fra> ans;
int r; string ask(int64 x)
{
if (!x)
return "";
string s;
s.clear();
while (x > ){
s.PB((x%) + '');
x /= ;
}
int size = SZ(s);
string ret;
ret.clear();
for (int i = size-; i >= ; i --)
ret.PB(s[i]);
return ret;
} string tostring()
{
string ret;
ret.clear();
ret += ask (ans[].a);
if (ans[].b == )
return ret;
ret += '/';
ret += ask (ans[].b);
return ret;
} int64 gcd(int64 a, int64 b){
if (!b) return a;
return gcd (b, a%b);
} fra Add(fra x, fra y){
y.b *= ;
if (x.b > y.b){
fra t = x;
x = y;
y = t;
}
while (x.b < y.b){
int64 g = gcd (x.b, y.b);
int64 mx = y.b / g, my = x.b / g;
x.a *= mx; x.b *= mx;
y.a *= my; y.b *= my;
}
fra ret;
ret.a = x.a + y.a;
ret.b = x.b;
while (!(ret.a % )){
ret.a /= ;
ret.b /= ;
if (ret.b == )
break;
}
return ret;
} VI match(int x){
VI ret;
ret.clear();
if (x == || x == ){
for (int i = ; i < ; i ++)
ret.PB(i);
}
if (x == || x == ){
ret.PB(); ret.PB();
ret.PB(); ret.PB();
}
if (x == || x == ){
for (int i = ; i < ; i ++)
ret.PB(i);
}
return ret;
} void change()
{
vector<fra> tmp;
tmp.clear();
for (int i = ; i < ; i ++){
VI x = match(i);
fra cnt;
cnt.clr();
for (int j = ; j < ; j ++)
cnt = Add (cnt, ans[x[j]]);
tmp.PB(cnt);
}
ans.clear();
ans = tmp;
} class Dragons
{
public:
string snaug(vector <int> initialFood, int rounds){
VI xx = initialFood;
if (xx[] == xx[] && xx[] == xx[] && xx[] == xx[] && xx[] == xx[] && xx[] == xx[])
return ask(xx[]);
r = rounds;
int64 size = SZ(xx);
fra x;
x.clr();
ans.clear();
for (int64 i = ; i < size; i ++){
x.a = xx[i];
ans.PB(x);
}
int T = ;
while (T < r){
T ++;
change ();
}
string s = tostring();
return (s);
}
//by plum rain
};
DIV 1 1000pt
tag:dp, good
题意:给定两个数字n(n <= 10),num(num <= 10^17),和vector<int> a[n],要求用n种颜色画出num面旗。
每面旗有x条竖条纹组成,条纹数不同的旗子一定不相同,条纹数相同但是对应条纹颜色不同的旗子也为不同的旗。
给条纹上色有一个条件,将n种颜色标为1~n,则如果a[i]中有数字k,则颜色i不能颜色k相邻(此时保证a[k]中一定有i)。
将所染旗帜中条纹数最多的旗帜的条纹数记为ans,求ans的最小值。
例如,n = 3,num = 10, a = {{0}, {1, 2}, {1, 2}},则染一条条纹的旗帜共有3种,染两条条纹的旗帜共有4种,染三条条纹的6种,3 + 4 + 6 = 13 >= 10,所以答案为3。
解法:首先肯定要用dp,而且dp部分很简单。难点在于,num可以达到10^17,意味着首先dp要注意空间复杂度优化,其次如果不特殊处理,肯定会超时。
考虑到,如果有任意一种颜色可以和两种颜色相邻,那么旗帜的条纹每增加一条所增加的染色种数是呈指数级增长的,ans也就很小,不会超时。
也就是说,只需要特判对每种颜色,能和它相邻的颜色都不超过1种的情况。
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <string>
#include <utility>
#include <map>
#include <ctime>
#include <stack> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;} bool fbd[][];
int n;
int64 dp[][];
int64 tot; void init(string s)
{
tot = ;
int pos = ;
int size = SZ (s);
while (pos < size){
tot = tot * + s[pos++] - '';
}
} int64 DP()
{
int64 ret;
int64 sum;
if (tot <= n)
return ;
int spe = true;
int64 add = ;
for (int i = ; i < n; i ++){
bool cnt = false;
for (int j = ; j < n; j ++){
if (fbd[i][j]) continue;
if (!cnt){
cnt = true;
add ++;
continue;
}
spe = false;
break;
}
}
if (spe){
ret = ;
sum = n;
int64 tim = (tot - sum) / add;
if (n + tim * add >= tot)
return (tim + );
else return (tim + );
}
int pos = ;
for (int i = ; i < n; i ++)
dp[][i] = ;
ret = ;
sum = n;
while (sum < tot){
for (int i = ; i < n; i ++){
dp[(pos+)%][i] = ;
for (int j = ; j < n; j ++){
if (fbd[i][j]) continue;
dp[(pos+)%][i] += dp[pos][j];
}
sum += dp[(pos+)%][i];
}
pos = (pos+) % ;
ret ++;
}
return ret;
} class Flags
{
public:
long long numStripes(string numFlags, vector <string> forbidden){
CLR(fbd);
init(numFlags);
n = SZ (forbidden);
for (int i = ; i < n; i ++){
string s = forbidden[i];
int size = SZ (s);
for (int j = ; j < size; j ++){
if (s[j] == ' ') continue;
fbd[i][s[j]-''] = true;
}
}
int64 ans = DP();
return (ans);
}
//by plum rain
};
SRM 148
DIV 1 1100pt
tag:recursion, good
题意:猜数字游戏,给定一个数字x,几个人分别猜测不同的数字,谁猜测数字与x之差最小谁赢,若有两人或多人与x之差相同且最小,则平手,平手不算赢!现在,题目给定数字n,m,数组{an}。
n表示猜数字范围为1~n,在你猜数字前已经有size(an)个人猜过数字,他们猜测的值记录在{an}中,在你猜之后,还将有m个人猜测。
不论你猜测哪个数字,在你之后猜测的人都采取最优策略(即使他自己赢的概率最大,如果猜两个数概率一样,猜小的),求猜多少能使你赢的概率最大。若有多个答案,输出最小的一个。
比如,n = 1000, {an} = {50}, m = 1。则答案为51, 因为当你猜51, 剩下的一个人为了使自己猜赢的概率最大,应该猜49或52,由于要猜小的,所以猜49,则你赢的概率为50,最优情况。
n <= 10^6,0 <= size(an) <= 10, 0 <= m <= 6, n ^ m <= 10^6。
解法:考虑递归。题目中的约束条件n ^ m <= 10^6可以起到提示的作用,但是如果直接暴力,时间复杂度为O(n^(m+1)),可能超时。考虑优化最后一个人猜测的情况。
在最后一个人猜测时情况为-----X--X--X-----X-----(---表示可猜测的点,X表示已猜测的点)
则,最后一个人可能猜测的点只有几个----OXO-XO-XO----XO----(最后一个人可能猜测的点为O),比较他们即可。
这样就用递归 + 枚举解决了问题。胆识程序很难写。因为对第m个人,他猜测的数字要影响第m+1个人,而m+1猜测的情况又会影响m。
我是参考了SnapDragon的代码。
#line 7 "NumberGuessing.cpp"
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <string>
#include <utility>
#include <map>
#include <ctime>
#include <stack> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ;
const int N = ; inline int MyMod( int a , int b ) { return (a%b+b)%b;} int n;
int num[], pnum;
int tot; void xequal(int an[], bool x)
{
if (x){
for (int i = ; i < tot; ++ i)
an[i] = num[i];
return ;
}
for (int i = ; i < tot; ++ i)
num[i] = an[i];
} int cal (int x, bool xxx)
{
int t[], tnum = tot;
xequal (t, );
if (xxx) tnum --;
sort (t, t+tnum);
if (tnum == -) return n;
if (x < t[])
return x + ((t[] - x - ) >> );
if (x == t[])
return x + ((t[] - x - ) >> );
int flag = ; //添加flag是为了不用特判x 与 t[i]会重合的情况
for (int i = ; i < tnum; ++ i){
if (x == t[i]) flag = ;
if (x < t[i])
return + ((t[i] - x - ) >> ) + ((x - t[i--flag] - ) >> );
}
return n - x + + ((x - t[tnum--flag]) >> );
} int findpos()
{
int t[], tnum = tot - ;
xequal (t, );
sort (t, t+tnum);
int ret, pret = ;
if (tnum == ) return ;
if (t[] > )
ret = t[] - , pret = cal (t[]-, );
for (int i = ; i < tnum; ++ i){
if (t[i] >= n) continue;
if (i < tnum- && t[i] + == t[i+])
continue;
int tmp = cal (t[i]+, );
if (tmp > pret)
ret = t[i] + , pret = tmp;
}
return ret;
} int DFS(int pos, int c)
{
pnum = pos + tot - c - ;
if (pos == c){
int tmp = findpos();
num[pnum] = tmp;
return tmp;
}
int ntmp[], ret, pret = ;
xequal(ntmp, );
for (int i = ; i <= n; ++ i){
bool xxx = true;
for (int j = ; j < pnum; ++ j)
if (num[j] == i){
xxx = false;
break;
}
if (!xxx) continue;
pnum = pos + tot - c - ;
num[pnum] = i;
DFS(pos+, c);
pnum = pos + tot - c - ;
int ptmp = cal (i, );
if (ptmp > pret)
pret = ptmp, ret = i, xequal (ntmp, );
}
xequal (ntmp, );
return ret;
} class NumberGuessing
{
public:
int bestGuess(int A, vector <int> B, int c){
int size = SZ (B);
n = A, tot = size + c + ;
CLR (num), pnum = -;
for (int i = ; i < size; ++ i)
num[++pnum] = B[i];
return DFS(, c);
}
//by plum rain
};
小结:受了别人的推荐,尝试做了一点topcoder的题,现在看了,这些题确实是很有价值的。
并且,这几天对自己做题时存在的两个问题感觉特别明显。
一是代码功底太差了。div2 lv3, div1 lv2,div1 lv3这三道题的代码都不小,每次我写完以后都要调试很久才能和自己的想的算法吻合。而且,上面有不少题的代码都是重写过的,因为之前写的错误太多,修改太麻烦,而且容易引出新的错误。
二是自己写前总是没有或者很难对自己要写的代码有一个比较准确的估计。比如有时把问题想简单了,有时又忽略了个别限制条件,写到一半或者写完了调试的时候才发现,然后又去改。这个时候更改,不仅浪费时间,而且很容易造成新的错误。
刷题!
SRM144 - SRM 148(少144-DIV1-LV3,147-DIV2-LV3)的更多相关文章
- jq对象转为dom对象:$(".div1")[0] dom对象转为jq对象:$(dom对象)
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- 第四篇:web之前端之jquery
前端之jquery 前端之jquery 本节内容 jquery简介 选择器和筛选器 操作元素 示例 1. jquery简介 1 jquery是什么 jQuery由美国人John Resig创建,至 ...
- Qt5图形视图框架的“俄罗斯方块”(使用了QGraphicsView)
Qt5 图形视图框架QGraphicsView 1.图形视图框架包含三大类:场景类(QGraphicsScene),视图类(QGraphicsView),图元类(QGraphicsItem): 2.对 ...
- ***CodeIgniter集成微信支付(转)
微信支付Native扫码支付模式二之CodeIgniter集成篇 http://www.cnblogs.com/24la/p/wxpay-native-qrcode-codeigniter.html ...
- Tomcat调优及JMX监控
Tomcat调优及JMX监控 实验背景 ====================================================== 系统版本:CentOS release 6.5 ( ...
- Dubbo详细介绍与安装使用过程
今天看到一篇不错的dubbo介绍教程,原文链接:http://blog.csdn.net/xlgen157387/article/details/51865289 1 Dubbo介绍 1.1 dubb ...
- SQLite XXTea加密学习
这几天优化数据库读写,移植了xxtea加密到最新的数据库sqlite 3.12.2里,一些好文章放在这里.移植后,数据库读写性能异常优秀! 这几天又发现,数据库还是发生了无法写入情况,数据库崩溃掉了. ...
- MySQL 第一篇
一.MySQL介绍 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司.MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数 ...
- 在JAVA中,关于反射机制的讨论
一.什么是反射机制 简单的来说,反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息. 二.哪里用到反射机制 ...
随机推荐
- hadoop-streaming 配置之---参数分割
map: -D stream.map.output.field.separator=. 定义mapoutput字段的分隔符为. 用户可以自定义分隔符(除了默认的tab) -D stream.num.m ...
- 按行N等分某个文件
# --*-- coding:utf-8 --*--import randomimport math def fanhui(): into = random.randint(1, 10) ...
- Firefly官方教程之DBentrust使用文档
原地址: http://bbs.gameres.com/thread_224185.html 1.dbentrust说明该模块主要是对数据库与memcached存储的处理.里面封装了从memcache ...
- VIM编辑命令的技巧
vim 选择文本,删除,复制,粘贴 文本的选择,对于编辑器来说,是很基本的东西,也经常被用到,总结如下: v 从光标当前位置开始,光标所经过的地方会被选中,再按一下v结束. V 从光标 ...
- java static 变量,和方法从属于类
第36集 java static 变量,和方法从属于类 可以用类来直接调用static属性和方法 static方法不能调用非静态的属性和方法,反之可以 new产生的对象,不包括static 属性和方法
- Android EditText的常用技巧
1. 设定 EditText 的滚动条.对齐方式.行数.和提示 (hint) 及其颜色 在布局文件,比如 main.xml 中,增加 < EditText android:id = ...
- JNI编程(二) —— 让C++和Java相互调用(2)
3.getRamdomOrder() 这个方法会从backend得到一个随机的Order对象(抱歉这里“Random”拼错了),然后再调用java中相应的通知方法来通知foreground.getRa ...
- 如何用C#获得文件信息以及扩展信息
在C#中获得文件信息很容易,只需要用FileInfo类或者FileVersionInfo类就可以获得,但是如果想要获得文件的扩展信息,则无法从这两类来获得.不过在C#中,这也不是件难事,只要引入“Mi ...
- 【HDOJ】3311 Dig The Wells
Steiner Tree.概念就不讲了,引入0号结点.[1, n+m]到0连一条边,权重表示挖井的费用.这样建图spfa求MST即满足所求解. /* 3311 */ #include <iost ...
- windows平台下VLC2.0.5编译
windows平台下VLC2.0.5编译说明 时隔一年多,又要搞流媒体了,不过这次是要做流媒体服务器. 暂时决定使用vlc+ffmpeg+live555,虽然听有些前辈说这个组合的性能较差,只能作为学 ...