(本套题算是比较温和吧,就是罚时有点高。

B .Baby Bites

题意:给出一个婴儿给出的数组,有一些数字听不清楚,让你还原,问它是否是一个从1开始的一次增加的数组。

思路:从左往右依次固定,看是否有矛盾即可。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
int a[]; char c[];
int main()
{
int N; bool F=true;
scanf("%d",&N);
rep(i,,N) {
scanf("%s",c+);
if(c[]=='m') a[i]=-;
else {
int L=strlen(c+);
rep(j,,L) a[i]=a[i]*+c[j]-'';
}
}
if(a[]==-) a[]=;
if(a[]!=) F=false;
rep(i,,N) {
if(a[i]==-&&a[i-]!=-) a[i]=a[i-]+;
if(a[i]!=-&&a[i-]!=-)
if(a[i]!=a[i-]+) F=false;
}
if(F) puts("makes sense");
else puts("something is fishy");
return ;
}

C .Code Cleanups

题意:给定N个物体,每个物品需要在第几天清扫。 你每次可以选择其中几个清扫,但是要满足你选择的集合拖欠的天数之和<20;问最小的清扫次数。

思路:贪心地取即可。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int a[];
int main()
{
int N,ans=; scanf("%d",&N);
rep(i,,N) scanf("%d",&a[i]);
rep(i,,N){
int now=,sum=,j=i; ans++;
while(j+<=N&&(sum+now*(a[j+]-a[j]))<)
sum+=now*(a[j+]-a[j]),now++,j++;
i=j;
}
printf("%d",ans);
return ;
}

E. Explosion Exploit

题意:给定N个自己人,M个敌人。以及每个人的血量ai。系统一共发起K次攻击,每次随机选择一个人物进行攻击,被攻击后血量少1,血量为0的不再考虑。问最后敌人都被杀死的概率。 (N,M<=5 ,ai<=6,K<=100)

思路:因为数据都比较小,我们可以考虑记忆化搜索,显然我们不能开10维数组来模拟,空间不够。  我们需要维护两个集合,分别是自己人的血量和敌人的血量,然后记忆化搜索。 集合我们可以用vector来表示,每次向下搜索前vector可以先排序,这样可以减很多的枝。   我的代码没用数组表示集合,用的是long long。

因为魔改了几次,所以代码比较丑。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
map<ll,double>mp; int N,M,K;
int a[],b[],sum,FCY; ll P[];
int c[],cnt;
void Change(ll &x){ //集合内部排序
ll res=;
for(int i=N;i>=;i--) a[i]=x%,x/=;
for(int i=M;i>=;i--) b[i]=x%,x/=;
sort(a+,a+N+); sort(b+,b+M+);
rep(i,,M) res=res*+b[i],c[N+M+-i]=b[i];
rep(i,,N) res=res*+a[i],c[N+-i]=a[i];
cnt=; rep(i,,N) if(a[i]) cnt++; rep(i,,M) if(b[i]) cnt++;
x=res;
}
double dfs(ll Now,int D)
{
Change(Now); int num=cnt,d[];
rep(i,,N+M) d[i]=c[i];
if(mp.find(Now)!=mp.end()) return mp[Now];
if(Now<FCY) return mp[Now]=1.0;
if(D==) return mp[Now]=0.0;
double res=;
rep(i,,N+M) {
if(d[i]==) continue;
d[i]--; if(d[i]==) num--;
res+=dfs(Now-P[i-],D-)/(num+(d[i]==));
if(d[i]==) num++; d[i]++;
} return mp[Now]=res;
}
int main()
{
scanf("%d%d%d",&N,&M,&K);
rep(i,,N) scanf("%d",&a[i]),sum+=a[i];
rep(i,,M) scanf("%d",&b[i]),sum+=b[i];
if(K>=sum) return puts("1.00000000"),;
ll Now=; FCY=; P[]=; cnt=N+M;
rep(i,,N+M) P[i]=P[i-]*;
rep(i,,M) Now=Now*+b[i],c[N+M+-i]=b[i];
rep(i,,N) Now=Now*+a[i],FCY*=,c[N+-i]=a[i];
printf("%.8lf\n",dfs(Now,K));
return ;
}

H .House Lawn

by 许

#include<bits/stdc++.h>
#define db double
#define ll long long
using namespace std;
const int maxn=1e6+,inf=1e9;
char str[];
struct node
{
char s[];
int id,p;
bool operator<(const node&t)const
{
if(p==t.p)return id<t.id;
return p<t.p;
}
}a[];
void gao(int cur,int &pri,int &c,int &t,int &r)
{
int n=strlen(str),i=;
pri=c=t=r=;
while(str[i]!=',')i++;
i++;
while(str[i]!=',')
pri=pri*+str[i++]-'';i++;
while(str[i]!=',')
c=c*+str[i++]-'';i++;
while(str[i]!=',')
t=t*+str[i++]-'';i++;
while(i<n)
r=r*+str[i++]-'';
}
int main()
{
int e,m,pri,c,t,r,v,n=,cnt=;
cin>>e>>m;
getchar();
for(int i=;i<=m;i++)
{
gets(str);
gao(i,pri,c,t,r);
v=n/(t+r)*t*c;
if(v<e)
{
int tmp=n%(t+r);
db v1=(db(e)-v)/c,v2=tmp-v1;
if(v1<=(db)t)
if(v1*r<=v2*t)v=e;
}
if(v>=e)
{
a[++cnt].p=pri; a[cnt].id=i;
int len=strlen(str),j=;
while(str[j]!=',')
a[cnt].s[j]=str[j],j++;
a[cnt].s[j]='\0';
}
}
sort(a+,a++cnt);
if(cnt==)puts("no such mower");
else
{
int i=;
while()
{
printf("%s\n",a[i++].s);
if(i>cnt||a[i].p>a[i-].p)break;
}
}
}

I .Intergalactic Bidding

题意:给出N个高精度数,表示N个人对应的数字,满足每个人的数字大于等于前面一个人的两倍,以及S。 输出winners,一个人是winner,当且仅当他存在一个集合里,这个集合是和是S。

思路:首先挖掘为何有大于等于两倍,我们发现它告诉我们每一个集合表示出来的数都是不同的,而每一个S对应的集合也是唯一的,所以要么没有winner,要么我们可以从大到小贪心地拼凑出S。

by 罗

elect Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=;
const int maxn=1e6+;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
string s;
int cmp(string a,string b){
if(a.length()>b.length())return true;
else if(a.length()<b.length())return false;
else return a>=b;
}
bool vis[];
struct node{
string name;
string money;
}my[];
bool cmpp(node a,node b){
if(a.money.size()>b.money.size())return true;
else if(a.money.size()<b.money.size())return false;
else return a.money>b.money;
}
string sub(string a,string b){
string ans="";
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
int len1=a.length(),len2=b.length();
int pre=;
for(int i=;i<len2;i++){
int now=a[i]-b[i];
if(now<)a[i+]--,now=+now;
ans+=(char)(now+'');
}
for(int i=len2;i<len1;i++){
int num=a[i]-'';
if(num<){
num+=;
a[i+]--;
}
ans+=(char)(num+'');
}
while(ans.size()>&&ans.back()=='')ans.pop_back();
reverse(ans.begin(),ans.end());
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie();
std::cout.tie();
int n;
cin>>n;
cin>>s;
for(int i=;i<=n;i++){
cin>>my[i].name>>my[i].money;
}
int num=;
sort(my+,my++n,cmpp);
for(int i=;i<=n;i++){
if(cmp(s,my[i].money)){
s=sub(s,my[i].money);
vis[i]=;
num++;
}
}
if(s==""){
cout<<num<<endl;
for(int i=;i<=n;i++){
if(vis[i])cout<<my[i].name<<endl;
}
}
else{
cout<<""<<endl;
}
return ;
}

J .Jumbled String

题意: 给你00,01,10,11的数量a,b,c,d。 让你根据信息还原一个字符串 。

思路:由00和11的数量,我们可以得到字符串中0和1的数量x和y,然后取凑即可, 注意00数量为0时,x可能为0,也可能为1,其它情况下,x唯一; y同理。

假设得到了x,y。 我们可以试着构造一个形如11111...0001000....1111的串,即中间可以夹杂一个1。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
const int Mod=1e9+;
map<int,int>mp;
bool check(int A,int D,int B,int C)// 0,1
{
if(1LL*A*D!=1LL*B+C) return false;
if(A==&&B==&&C==){
rep(i,,D) putchar(''); return true;
}
if(D==&&B==&&C==){
rep(i,,A) putchar(''); return true;
}
int num=B/A,rem=B%A;
rep(i,,D-num-(rem!=)) putchar('');
rep(i,,A) {
putchar('');
if(rem==i) putchar('');
}
rep(i,,num) putchar('');
return true;
}
int main()
{
int A,B,C,D;
rep(i,,){
int tmp;
if(i&) tmp=(i-)/*i;
else tmp=i/*(i-);
mp[tmp]=i;
}
scanf("%d%d%d%d",&A,&B,&C,&D);
if(mp[A]==) return puts("impossible"),;
if(mp[D]==) return puts("impossible"),;
if(check(mp[A],mp[D],B,C)) return ;
if(A==&&check(,mp[D],B,C)) return ;
if(D==&&check(mp[A],,B,C)) return ;
if(A==&&D==&&check(,,B,C)) return ;
puts("impossible");
return ;
}

K .King's Colors

题意:给你N,K,一棵大小为N的树,求刚好染K种色,而且相邻边颜色不同的方案数。

思路:一眼容斥题,我们用F(x)表示颜色大于等于x的方案数,则ans=F(K)*C(K,K) -F(K-1)*C(K,K-1)+F(K-2)*C(K,K-2)...

而这又是一棵树,所以我们从上到下染色,每个点只要和父亲颜色不同即可。 所以F(x)=x*(x-1)^(N-1);

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
const int Mod=1e9+;
int C[maxn][maxn],N,K,ans;
int qpow(int a,int x)
{
int res=; while(x){
if(x&) res=(ll)res*a%Mod;
a=(ll)a*a%Mod; x>>=;
} return res;
}
int main()
{
rep(i,,) C[i][]=C[i][i]=;
rep(i,,)
rep(j,,i) C[i][j]=(C[i-][j-]+C[i-][j])%Mod;
scanf("%d%d",&N,&K);
rep(i,,N){
int u; scanf("%d",&u);
}
for(int i=K;i>=;i--){
if((K-i)%==){
(ans+=(ll)i*qpow(i-,N-)%Mod*C[K][i]%Mod)%=Mod;
}
else {
ans=((ans-(ll)i*qpow(i-,N-)%Mod*C[K][i]%Mod)%Mod+Mod)%Mod;
}
}
printf("%d\n",ans);
return ;
}

Gym .101933 Nordic Collegiate Programming Contest (NCPC 2018) (寒假gym自训第四场)的更多相关文章

  1. (寒假GYM开黑)2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

    layout: post title: 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) author: &qu ...

  2. 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)- D. Delivery Delays -二分+最短路+枚举

    2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)- D. Delivery Delays -二分+最短路+枚举 ...

  3. 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)-E. Explosion Exploit-概率+状压dp

    2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)-E. Explosion Exploit-概率+状压dp [P ...

  4. 2019年湖南多校第一场||2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

    第一场多校就打的这么惨,只能说自己太菜了,还需继续努力啊- 题目链接: GYM链接:https://codeforces.com/gym/101933 CSU链接:http://acm.csu.edu ...

  5. 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) D. Delivery Delays (二分+最短路+DP)

    题目链接:https://codeforc.es/gym/101933/problem/D 题意:地图上有 n 个位置和 m 条边,每条边连接 u.v 且有一个距离 w,一共有 k 个询问,每个询问表 ...

  6. 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) A. Altruistic Amphibians (DP)

    题目链接:https://codeforc.es/gym/101933/problem/A 题意:有 n 只青蛙在一个坑里面,要求可以跳出坑的青蛙的最大数量.每个青蛙有 3 种属性:l 为青蛙一次可以 ...

  7. 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) - 4.28

    赛后补了几道 赛中我就写了两个... A - Altruistic AmphibiansGym - 101933A 看了眼榜没几个人做.就没看. 最后发现就是一个DP(但是我觉得复杂度有点迷) 题意: ...

  8. 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) Solution

    A. Altruistic Amphibians Upsolved. 题意: $有n只青蛙,其属性用三元组表示 <l_i, w_i, h_i> l_i是它能跳的高度,w_i是它的体重,h_ ...

  9. [十一集训] Day1 (2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018))

    A Altruistic Amphibians 原题 题目大意: n只青蛙在高度为d的井中,每只有跳跃距离.重量和高度,每只青蛙可以借助跳到别的青蛙的背上而跳出井,每只青蛙能承受的最大重量是自身重量, ...

随机推荐

  1. MySQL设置白名单教程

    1 登录mysql mysql -h host -u username -p password 2 切换至mysql库 use mysql; 3 查看当前允许登录IP及用户 select Host,U ...

  2. jedata日期控件的开始结束日期设置

    <span class="wstxt">开始日期:</span><input type="text" class="wo ...

  3. 码云git使用四(分支的创建,使用和合并)

    我们在使用git的时候,一般都不是直接在主代码中开发, 通常我们做的操作是创建一个分支,我们在分支上开发,开发完毕,在提交到主代码中. 我们现在学习创建分支,合并分支. 1.首先我们下载到本地都是在主 ...

  4. ACCESS数据库基本使用

    ACCESS是Office自带的数据库,使用起来非常方便. 相比,其它数据库来说,使用率较低,但是同MYSQL一样,免费.正因为如此,所以很多建站的程序员,还是会选择使用它. 部分代码: <sc ...

  5. linux系统管理 计划任务

    一次性计划任务 命令: at 语法: at [-f 文件名] 时间 绝对计时方法 HH:MM yyyy-MM-dd 相对计时方法 now + n minutes now+n hours now + n ...

  6. day03 is 与== 常量

    is身份运算:比较的是id是否相等 ==判断值是否相等 ... 值相等id不一定相等 >>>x=1111111111111111111111111111111111111111111 ...

  7. WPF 创建自定义控件及自定义事件

    1 创建自定义控件及自定义事件 /// <summary> /// 演示用的自定义控件 /// </summary> public class ExtButton : Butt ...

  8. 【转载二】Grafana系列教程–Grafana的下载及安装

    本篇教程,waitig 来为大家介绍一下Grafana的安装及运行的方式. 更多Grafana技术请加入<InfluxDB&Grafana技术交流群:580487672(点击加入)> ...

  9. shell脚本总结

    1.变量 A:  定义变量A=1,只会对自己所在的shell进程有效 B: 定义变量export B=1,会对自己所在的shell进程及其子进程生效 C: 在script.sh脚本中定义的变量,在当前 ...

  10. 6.2 C++ string类型字符串的连接

    参考:http://www.weixueyuan.net/view/6391.html 总结: 对于string类型变量,我们可以直接用“+”或者“+=”进行字符串的连接,操作符非常方便. 用“+”风 ...