SRM475 - SRM479(1-250pt,500pt)
SRM 475
DIV1 300pt
题意:玩游戏。给一个棋盘,它有1×n(1行n列,每列标号分别为0,1,2..n-1)的格子,每个格子里面可以放一个棋子,并且给定一个只含三个字母WBR,长度为n的字符串,代表每个格子的颜色。在游戏开始时,r个棋子随机摆放在这n个格子里(每个棋子摆在每个格子里的概率相同),问游戏结束时,这些格子里所剩棋子数的期望。游戏的规则为(记这个棋盘的列数为size):
1、如果棋子在0格,则向右移动一格;
2、如果棋子在size-1或size-2格,则向左移动一格;
3、其他棋子若在颜色为W的格子则左移一格,若在颜色为B的格子则右移一格,若在颜色为R的格子:若该旗子目前并未移动过,则左移一格,否则返回上一步所在的格子。
4、所有棋子移动完成后,对与所有格子,如果某个格子含有不止一个棋子,则将该格所有棋子移出棋盘。
5、第4步完成后,棋盘的列数减少1,(即从1*size大小的棋盘变为1*(size-1)),若棋盘列数等于2,则游戏结束,否则循环进行1-5步。
2 <= n <= 17
解法:由于棋盘大小最多也就1*17格,可以直接暴力模拟所有情况,最慢也就O(C(17,8) * 17)的复杂度,能接受。
但是,题解给出了一种很好的方法。
首先,通过观察发现以下几点:1、称“游戏开始时出现在奇数格的棋子“为奇数棋,其他称为偶数棋。经过一次1-3步循环,所有奇数棋变为偶数棋或者被移出棋盘,所有偶数棋变为奇数棋或被移出棋盘。
2、每次将某一格的棋子移出棋盘,移出的数量必定为2,且移出的全为奇数棋或者全为偶数棋。换句话说,如果游戏开始时,奇数棋的数量为奇数(偶数),游戏结束时,奇数棋数量也为奇数(偶数)。偶数棋也如此。
3、游戏结束时,棋盘大小一定为1*2,并且每格含有0个或1个棋子。也就是说,游戏结束时剩下0个或1个奇数棋,0个或1个偶数棋。
由1,2,3可以得出结论,若游戏开始时有x个奇数棋,有y个偶数棋,则游戏结束时有(x%2 + y%2)个棋子。然后,遍历所有游戏开始时可能出现的棋子摆放情况即可。
tag:think, good
/*
* Author: plum rain
* score : 0
* study form: www.topcoder.com
*/
#line 11 "RabbitStepping.cpp"
#include <sstream>
#include <stdexcept>
#include <functional>
#include <iomanip>
#include <numeric>
#include <fstream>
#include <cctype>
#include <iostream>
#include <cstdio>
#include <vector> using namespace std; #define SZ(v) ((int)(v).size()) class RabbitStepping
{
public:
double getExpected(string field, int r){
int n = SZ (field);
int num = , sum = ;
for (int i = ; i < (<<n); ++ i){
if (__builtin_popcount(i) != r) continue; int e = , o = ;
for (int j = ; j < n; ++ j)
if (i & (<<j)){
e += j & ;
o += - (j&);
}
num += (e%) + (o%);
++ sum;
}
return (num + 0.0) / sum;
}
};
DIV1 600pt
题意:第一年7月天上掉下一对小兔子。之后每年3月,老兔子生一对小兔子,原来的小兔子升级为老兔子;某些年的11月,消失一半兔子,消失的兔子总是年龄较大的那些。现在给定最多50个兔子会消失一半的年份,问第K(K<=1e7)年的12月一共有多少兔子。答案模MOD=1,000,000,009。
解法:不会- -
tag:math, good
SRM 476
DIV1 250pt
题意:有n只羊,给定两个数组{an}和{bn},ai表示第i只羊的食量,bi表示第i只羊的附加食量,并且给定拥有的食物总量为tot。如果主人饲养了m只羊,则对于一只羊k,它消耗的食物总量为a[k] + m*b[k]。要求所有羊消耗的食物总量之和不超过tot的情况下,求饲养的羊的数量最多为多少只。
(1<= n <= 50)
解法:主人养k只羊时花费食物总量最少为t,则可以t可以在O(nlogn)(使用一次快排即可)。然后从k = n to 1找最多可能饲养的羊的数量。
tag:greedy
/*
* Author: plum rain
* score : 204.20
*/
#line 11 "Badgers.cpp"
#include <sstream>
#include <stdexcept>
#include <functional>
#include <iomanip>
#include <numeric>
#include <fstream>
#include <cctype>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm> using namespace std; #define PB push_back
#define SZ(v) ((int)(v).size())
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl typedef vector<int> VI; class Badgers
{
public:
int feedMost(vector <int> hun, vector <int> g, int tot){
int size = SZ (hun);
VI tmp;
for (int n = size; n > ; -- n){
tmp.clear();
for (int i = ; i < size; ++ i)
tmp.PB (hun[i] + g[i]*(n-));
sort (tmp.begin(), tmp.end()); int num = ;
for (int i = ; i < n; ++ i)
num += tmp[i];
if (num <= tot) return n;
}
return ;
}
};
DIV1 550pt
题意: 小明有一些朋友(n个),小明的朋友还有一些朋友,他们可能是小明的朋友也可能不是。一共有m个人,他们的房子标号为1-m。小明要从自己家(1号房子)出发,然后去拜访自己的朋友。每次,小明所在的房子的主人都会对房子主人自己的朋友进行一次随机排列,小明只能从前k个人中选择一个人拜访,或者不再拜访任何人。注意,选择的这个人必须是小明没有拜访过的,并且他是小明的朋友。问,在小明采取最优策略下,他能拜访完所有朋友的概率最大是多少。
每个人最多15个朋友,一共最多36个人,K >= 1。
解法:首先,要用状态压缩,用opt表示小明的所有朋友(最多15个)是否被拜访过,1为未拜访。数组dp[i][j]表示拜访状态为i,现在在房子j的状态下能拜访完所有朋友的概率。
dp[i][j] = sum{(给出随机排列后,小明会选择t作为下一个拜访地点的可能性) * dp[i^(1<<t)][t]}(t为所有小明的朋友, 且i & (1<<t)为真)。
上面状态转移方程只剩下一个问题没有解决,就是“给出随机排列后,小明会选择t作为下一个拜访地点的可能性”,而这个可以通过讨论dp[i^(1<<t)][t]的大小易求,具体见代码。
tag:状压dp, good
/*
* Author: plum rain
* score : 0
*/
#line 11 "FriendTour.cpp"
#include <sstream>
#include <stdexcept>
#include <functional>
#include <iomanip>
#include <numeric>
#include <fstream>
#include <cctype>
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <utility> 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 typedef vector<int> VI; int C[][], num[];
double dp[<<][];
bool pat[][];
VI m;
int n, k; void C_table(int maxx)
{
CLR (C);
C[][] = ;
for (int i = ; i <= maxx; ++ i){
C[i][] = C[i][i] = ;
for (int j = ; j < i; ++ j)
C[i][j] = C[i-][j] + C[i-][j-];
}
} bool cmp(pair<double, int> a, pair<double, int> b)
{
return a.first > b.first;
} double choose(int num, int pos)
{
if (num < k)
return (double)(pos == );
if (num - pos < k) return 0.0;
return (double)C[num-pos-][k-] / C[num][k];
} double gao (int opt, int pos)
{
vector<pair<double, int> > cur; cur.clear();
for (int i = ; i < n; ++ i)
if (opt&(<<i) && (pos == - || pat[m[pos]][m[i]]))
cur.PB(make_pair(dp[opt^(<<i)][i], i)); sort (cur.begin(), cur.end(), cmp);
double ret = 0.0;
for (int i = ; i < SZ (cur); ++ i)
ret += choose(pos==-?n:num[m[pos]], i) * dp[opt^(<<cur[i].second)][cur[i].second];
return ret;
} class FriendTour
{
public:
double tourProbability(vector <string> fri, int K){
C_table(); CLR (pat); CLR (num); m.clear();
int tmp = ;
for (int i = ; i < SZ (fri); ++ i){
string s = fri[i]; tmp = ;
for (int j = ; j < SZ (s); ++ j){
if (j == SZ(s)- || s[j] == ' '){
if (j == SZ(s)-)
tmp = tmp * + s[j] -'';
-- tmp;
if (!i) m.PB (tmp);
pat[i][tmp] = ;
++ num[i];
tmp = ;
continue;
}
tmp = tmp * + s[j] - '';
}
}
n = SZ (m); k = K; CLR (dp);
for (int i = ; i < n; ++ i) dp[][i] = 1.0;
for (int i = ; i < (<<n); ++ i)
for (int j = ; j < n; ++ j)
dp[i][j] = gao (i, j);
return gao((<<n)-, -);
}
};
SRM 477
DIV1 250pt
题意:摆放六边形形成如下图案,然后将所有六边形涂成红蓝两色,求两种颜色的的六边形的公共边的总长度。
解法:直接分类讨论就好。题解的代码比我的代码简洁多了- -
tag:water
/*
* Author: plum rain
* score : 176.61
*/
#line 11 "Islands.cpp"
#include <sstream>
#include <stdexcept>
#include <functional>
#include <iomanip>
#include <numeric>
#include <fstream>
#include <cctype>
#include <iostream>
#include <cstdio>
#include <vector> using namespace std; #define SZ(v) ((int)(v).size())
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl typedef vector<string> VS;
VS k; int count (int x, int y)
{
int ret = ;
if (k[x][y+] == '.') ++ ret;
if (k[x][y-] == '.') ++ ret; if (x & ){
if (x > ){
if (k[x-][y] == '.') ++ ret;
if (y+ < SZ(k[x-]) && k[x-][y+] == '.') ++ ret;
}
if (x < SZ(k)-){
if (k[x+][y] == '.') ++ ret;
if (y+ < SZ(k[x+]) && k[x+][y+] == '.') ++ ret;
}
return ret;
} if (x > && k[x-][y] == '.') ++ ret;
if (x > && y > && k[x-][y-] == '.') ++ ret;
if (x+ < SZ(k) && k[x+][y] == '.') ++ ret;
if (x+ < SZ(k) && y > && k[x+][y-] == '.') ++ ret;
return ret;
} class Islands
{
public:
int beachLength(vector <string> kin){
k.clear();
k = kin;
int n = SZ (k);
int ans = ;
for (int i = ; i < n; ++ i){
string s = k[i];
int len = SZ (s);
for (int j = ; j < len; ++ j)
if (s[j] == '#') ans += count (i, j);
}
return ans;
}
};
DIV1 500pt
题意:如果数组(a, b)满足以下条件:1、存在a*a + b*b = c*c且a,b,c均为整数;2、a,b互素。则称a,b为好数组。给定n个数(可能重复),求从中最多可以拿出多少对好数组。
解法:有两种方法,可以将每个数拆成两个点然后求一个二分图最大匹配,ans = 匹配数/2;另一种方法,由题目条件容易推得,a,b必为一奇一偶。所以做一个奇偶二分图匹配即可。可是我不会二分图匹配- -,所以不会做.....
tag:二分图最大匹配
SRM 479
DIV1 250pt
题意:有一排座位1-n,每个座位上的客人需要咖啡或者茶,服务员每次在第0号位置将水壶添满茶或者咖啡,需要47秒。服务员的水壶装满一次只能给7个需求相同(茶或者咖啡)人倒,服务员从每个座位k走到k-1或者k+1需要1秒,给每个人倒水需要4秒。给出每个客人的需求,问服务员满足所有客人的需求所需要的最短时间。
解法:贪心即可。之前自己写的代码好搓,还错了- -,然后看了summary里面别人的代码,自己又写了一份。
tag:greedy
SRM475 - SRM479(1-250pt,500pt)的更多相关文章
- SRM 358(1-250,500pt)
DIV1 250pt 题意:电视目前停留在第100台,有一个遥控器,可以向上或向下换台(需要按键一次),也可以按一些数字,然后直接跳到该台(需要按键次数等于数字数,不需要按确定键).但是,这个遥控一些 ...
- SRM 601(1-250pt,500pt)
DIV1 250pt 题意:有很多袋子,里面装有苹果和橘子(也可能没有),给出每个袋子里有多少个苹果,多少个橘子.如果每个袋子里含有水果的总数都不小于x个,则可以从每个袋子里都拿出x个水果(拿出苹果和 ...
- SRM468 - SRM469(1-250pt, 500pt)
SRM 468 DIV1 250pt 题意:给出字典,按照一定要求进行查找. 解法:模拟题,暴力即可. tag:water score: 0.... 这是第一次AC的代码: /* * Author: ...
- SRM470 - SRM474(1-250pt,500pt)(471-500pt为最短路,474-500pt未做)
SRM 470 DIV1 250pt 题意:有n个房间排成一排,相邻两个房间之间有一扇关闭着的门(共n-1扇),每个门上都标有‘A’-‘P’的大写字母.给定一个数n,表示第n个房间.有两个人John和 ...
- SRM479
250pt: 题意:有一排一共44,777,777个人,每个人需要咖啡或者茶,队伍的头部有一台饮料机,有一个空姐负责给所有人送饮料,她一开始在也头部.空姐拿一个水壶,一开始是空的,可以在饮料机的地方加 ...
- SRM475
250pt: 题意:有最长N=17的一条格子,每个格子是W.B和R三种颜色之一,当某个格子上有兔子时,下一个回合该兔子按照以下的规则移动: 如果兔子在第一个格子,则向右移动一格: 否则如果兔子在倒数两 ...
- SRM DIV1 500pt DP
SRM 501 DIV1 500pt SRM 502 DIV1 500pt SRM 508 DIV1 500pt SRM 509 DIV1 500pt SRM 511 DIV1 500pt SRM 5 ...
- SRM 600(1-250pt,500pt)
DIV1 250pt 题意:给定一个vector<int>A,若能从里面选出一些数,使得他们按位或的值为x,则称x为吉利数.给定k,问最少要从A里面去掉多少个数,才能使k变为不吉利数. 解 ...
- SRM593(1-250pt,500pt)
SRM 593 DIV1 250pt 题意:有如下图所示的平面,每个六边形有坐标.将其中一些六边形染色,要求有边相邻的两个六边形不能染同一种颜色.给定哪些六边形需要染色,问最少需要多少种颜色. 解法: ...
随机推荐
- 解决Ubuntu 14.04 下SMPlayer的字幕乱码问题
1.SMPlayer播放器 对于使用ubuntu系统的同学,虽然系统初始就带有vedio播放器,但是这里强烈推荐SMPlayer,直接在Ubuntu Software Center中就可以免费下载安装 ...
- codevs 1282 约瑟夫问题(线段树)
#include<iostream> #include<cstdio> #include<cstring> #define maxn 30010 using nam ...
- ADO.NET和ORACLE操作数据库传参数赋值的方式
在使用.Net使用OracleParameter进行Oracle数据库操作的时候,因为Oracle和SQLServer针对查询参数化的语法不同, 在操作SQLServer的时候使用的是@Paramet ...
- Dhroid框架笔记(IOC、EventBus)
dhroid 目前包含了6大组件供大家使用1.Ioc容器: (用过spring的都知道)视图注入,对象注入,接口注入,解决类依赖关系2.Eventbus: android平台事件总线框架,独创延时事件 ...
- left ,right ,cross ,full/left outer join/区别 详解
--创建测试表wwif OBJECT_ID('qq') is not null drop table qqcreate table qq([序号] varchar(5),[内容1] varchar(1 ...
- UIWebView(本地数据部分)
创建UIWebView和UISegmentedControl webView用于显示内容,segmentedControl用于切换读取内容的类型 为了方便起见 用拖拉控件形式布局完界面 /* 使用UI ...
- JavaScript那些事儿(01): 对象
一. 对象是什么 是单身童鞋们正在查找的“对象”吗?是的,他/她就是活生生的对象. Javascript是一种基于对象的语言, 你遇到的所有东西几乎都是对象. 但它又不同于基于类的语言.那么“类”又是 ...
- 简单的js反选,全选,全不选
<html> <head> <base href="<%=basePath%>"> <title>My JSP 'che ...
- tomcat启动报错:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined At least one of these environment variable
linux 下 启动tomcat 报: Neither the JAVA_HOME nor the JRE_HOME environment variable is definedAt least o ...
- C++ 性能剖析 (一)
C++ 性能剖析 (一) 性能问题也不是仅仅用“技术”可以解决的,它往往是架构,测试,假设等综合难题.不过,对于一个工程师来说,必须从小做起,把一些“明显”的小问题解决.否则的话积小成多,千里堤坝,溃 ...