2018 icpc 青岛
https://zoj.pintia.cn/contests/91827364639/problems
C
要把这两个二进制串变为相同,需要先看哪些位置不同,设为数组c,某位为1则两位不同。
分1形成两段、四段或者更多段来考虑。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <set>
#include <cmath>
#include <queue>
#include <map>
#define ll long long
#define ld double
#define lson rt << 1, l, m
#define pi acos(-1)
#define rson rt << 1 | 1, m + 1, r
#define fo(i, l, r) for (long long i = l; i <= r; i++)
#define fd(i, l, r) for (long long i = r; i >= l; i--)
#define mem(x) memset(x, 0, sizeof(x))
#define eps 1e-10
using namespace std;
const ll maxn = ;
const ll mod = ;
ll read()
{
ll x = , f = ;
char ch = getchar();
while (!(ch >= '' && ch <= ''))
{
if (ch == '-')
f = -;
ch = getchar();
};
while (ch >= '' && ch <= '')
{
x = x * + (ch - '');
ch = getchar();
};
return x * f;
}
int n,m;
char s[maxn],t[maxn];
int pt[];
ll ans;
int main()
{ int T;
T = read();
int tt = ;
while (T--)
{
ans=;
n=read();
scanf("%s",s+);
scanf("%s",t+);
fo(i,,n){
s[i]-='';
t[i]-='';
s[i] ^= t[i];
}
int cnt = ;
fo(i,,n){
if(s[i]&&!s[i-]){
pt[++cnt]=i;
}
if(s[i]&&!s[i+]){
pt[++cnt]=i;
}
if(cnt>)break;
}
if(cnt>){
printf("0\n");
continue;
}
if(cnt==){
ans=(ll)n*(n+)/;
}
if(cnt==){
ans=n+n-;
}
if(cnt==){
ans=;
}
printf("%d\n",ans); } return ;
}
M
递归,碰到循环节就停止。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <set>
#include <cmath>
#include <queue>
#include <map>
#define ll long long
#define ld double
#define lson rt << 1, l, m
#define pi acos(-1)
#define rson rt << 1 | 1, m + 1, r
#define fo(i, l, r) for (long long i = l; i <= r; i++)
#define fd(i, l, r) for (long long i = r; i >= l; i--)
#define mem(x) memset(x, 0, sizeof(x))
#define eps 1e-10
using namespace std;
const ll maxn = ;
const ll mod = ;
ll read()
{
ll x = , f = ;
char ch = getchar();
while (!(ch >= '' && ch <= ''))
{
if (ch == '-')
f = -;
ch = getchar();
};
while (ch >= '' && ch <= '')
{
x = x * + (ch - '');
ch = getchar();
};
return x * f;
}
ll x,k;
ll f[] = {,,,,,,,,,};
ll g(int d,ll x){
if(d==) return x;
if(x==||x==){
return x^(d&);
}
ll ret = ;
while(x){
ret += f[x%];
x /= ;
}
return g(d-,ret);
}
int main()
{ int T;
T = read();
int tt = ;
while (T--)
{
x=read();k=read();
printf("%lld\n",g(k,x));
}
return ;
}
J
正好买m本书,还要带的钱最多。
考虑到,如果跳过若干本书,买一本,那把后一本书换成一开始跳过的书,答案会增加。
即,不存在这样的情况,买的书肯定是从1开始到m。
这个时候答案依然可能增加,要保证之后买不了书,就是加上之后价格最小的那本书-1
再判断一些特殊情况就可以。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <set>
#include <cmath>
#include <queue>
#include <map>
#define ll long long
#define ld double
#define lson rt << 1, l, m
#define pi acos(-1)
#define rson rt << 1 | 1, m + 1, r
#define fo(i, l, r) for (long long i = l; i <= r; i++)
#define fd(i, l, r) for (long long i = r; i >= l; i--)
#define mem(x) memset(x, 0, sizeof(x))
#define eps 1e-10
using namespace std;
const ll maxn = ;
const ll mod = ;
ll read()
{
ll x = , f = ;
char ch = getchar();
while (!(ch >= '' && ch <= ''))
{
if (ch == '-')
f = -;
ch = getchar();
};
while (ch >= '' && ch <= '')
{
x = x * + (ch - '');
ch = getchar();
};
return x * f;
}
int n,m;
ll a[maxn],ans;
int main()
{ int T;
T = read();
int tt = ;
while (T--)
{
ans=;
n=read();m=read();
fo(i,,n){
a[i]=read();
if(!a[i]){
i--;
n--;
m--;
}
}
if(m<||m>n){
printf("Impossible\n");
continue;
}
if(m==n){
printf("Richman\n");
continue;
}
fo(i,,m){
ans += a[i];
}
ll mn = 1e10;
fo(i,m+,n){
mn = min(mn,a[i]);
}
mn--;
ans+=mn;
printf("%lld\n",ans);
} return ;
}
E
试着将操作进行分解,前进n次,倒退n次,把这些操作全部换成前进1次,倒退1次的操作,答案不会变劣。
首先二分,检验的时候,不断往前走,如果某个时刻发现前一个点不能满足要求,就在这两个点之间反复的跳,注意考虑最后一个点的情况。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <set>
#include <cmath>
#include <queue>
#include <map>
#define ll long long
#define ld double
#define lson rt << 1, l, m
#define pi acos(-1)
#define rson rt << 1 | 1, m + 1, r
#define fo(i, l, r) for (long long i = l; i <= r; i++)
#define fd(i, l, r) for (long long i = r; i >= l; i--)
#define mem(x) memset(x, 0, sizeof(x))
#define eps 1e-10
using namespace std;
const ll maxn = ;
const ll mod = ;
ll read()
{
ll x = , f = ;
char ch = getchar();
while (!(ch >= '' && ch <= ''))
{
if (ch == '-')
f = -;
ch = getchar();
};
while (ch >= '' && ch <= '')
{
x = x * + (ch - '');
ch = getchar();
};
return x * f;
}
ll a[maxn],b[maxn],c[maxn];
ll n,m,mx;
bool check(ll t){
int nown = n;
fo(i,,n){
b[i]=t/a[i];
if(b[i]*a[i]<t)b[i]++;
}
b[n+]=;
while(nown>=&&b[nown]==)nown--;
fo(i,,nown+){
if(i<=n)c[i]=;
else c[i]=;
if(b[i-]>c[i-]){
c[i] += b[i-]-c[i-];
c[i-]=b[i-];
}
if(i==n&&c[i]>b[i])c[i]--; }
ll ret = ;
fo(i,,nown+){
ret += c[i];
if(ret > m) return false;
}
return true;
}
int main()
{ int T;
T = read();
int tt = ;
while (T--)
{
n=read();m=read();
mx=;
fo(i,,n){
a[i]=read();
mx=max(mx,a[i]);
}
ll lp = ,rp = mx*m,mid,ans=;
while(lp<=rp){
mid = (lp + rp) >> ;
if(check(mid)){
ans = mid;
lp = mid + ;
}else{
rp = mid - ;
}
}
printf("%lld\n",ans);
} return ;
}
F
首先,n个人最多打n-1轮,奇数个人不能打。
2、4个人都能打,然后发现6个人连两轮都打不了。
一开始是 2 1 4 3 6 5,假如说之后1个3打,按照只能要求1 2 3 4之间有比赛,5还是只能跟6打,因为第二轮与人的序号无关,这时候怎么调整都是徒劳。
人数是2^n的时候比较好安排,轮换一下就可以。
人数不是2^n的时候,还是按照2^n的情况排个表,因为之前就是保证字典序最小,所以编号大的都尽量出现在后面,如果这个时候表中出现了不得不跟一个不存在的大号打的情况,这个时候就安排不了了。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include <set>
#include <queue>
#define ll long long
#define ld long double
#define lson l,m,rt<<1
#define pi acos(-1)
#define rson m+1,r,rt<<1|1
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define fd(i,l,r) for(int i = r;i >= l;i--)
#define mem(x) memset(x,0,sizeof(x))
#define eps 3e-11
using namespace std;
const int maxn = ;
const ll inf = 1e9;
const ll mod = ;
ll read() {
ll x=,f=;
char ch=getchar();
while(!(ch>=''&&ch<='')) {
if(ch=='-')f=-;
ch=getchar();
};
while(ch>=''&&ch<='') {
x=x*+(ch-'');
ch=getchar();
};
return x*f;
}
int n,k;
int a[][];
int main() {
a[][]=a[][]=;
a[][]=a[][]=;
for(int t = ;t <= ;t <<= ){
fo(i,,t){
fo(j,,t){
a[t+i][t+j] = a[i][j];
a[t+i][j] = a[i][t+j] = a[i][j] + t;
}
}
}
int T=read();
while(T--){
n=read();k=read();
if((n&)||k>=n){
puts("Impossible");
continue;
}
bool flag = false;
fo(i,,k){
fo(j,,n){
if(a[i+][j] > n)flag=true;
}
}
if(flag){
puts("Impossible");
continue;
}
fo(i,,k){
fo(j,,n){
printf("%d",a[i+][j]);
putchar(j==n?'\n':' ');
}
}
}
return ;
}
D
枚举两个数的第一位,之后所有的位都确定了。
注意两位数不能有前导零,每一位的范围不能超。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include <set>
#include <queue>
#define ll long long
#define ld long double
#define lson l,m,rt<<1
#define pi acos(-1)
#define rson m+1,r,rt<<1|1
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define fd(i,l,r) for(int i = r;i >= l;i--)
#define mem(x) memset(x,0,sizeof(x))
#define eps 3e-11
using namespace std;
const int maxn = ;
const ll inf = 1e9;
const ll mod = ;
ll read() {
ll x=,f=;
char ch=getchar();
while(!(ch>=''&&ch<='')) {
if(ch=='-')f=-;
ch=getchar();
};
while(ch>=''&&ch<='') {
x=x*+(ch-'');
ch=getchar();
};
return x*f;
}
ll n,m,len;
char s[maxn];
int a[maxn],b[maxn];
bool flag;
inline int check(int u,int v,int t){
if(a[u]*b[v]==s[t])return ;
if(t<len&&s[t]&&(s[t]*+s[t+])==a[u]*b[v]) return ;
return ;
}
inline int dv(int v,int t){
if(s[t]%v==) return s[t]/v;
if(t<len&&(s[t]*+s[t+])%v==) return (s[t]*+s[t+])/v;
return -;
}
bool check(int st){
int t = st,u=,v=,sgn;
while(t<=len){
v++;
if(v>m){
v=;
u++;
}
if(u>n)break;
if(u==){
b[v]=dv(a[u],t);
if(b[v]==-||b[v]>=)return false;
}else if(v==){
a[u] = dv(b[v],t);
if(a[u]==-||a[u]>=)return false;
}else{
sgn=check(u,v,t);
if(!sgn)return false;
}
t++;
if(a[u]*b[v]>=)t++;
}
return u==n&&v==m&&t==len+;
}
bool gao(){
int sgn;
fo(i,,){
fo(j,,){
a[]=i;b[]=j;
sgn=check(,,);
if(!sgn)continue;
if(check(sgn+))return true;
}
}
return false;
}
int main() {
int T=read();
while(T--){
flag=false;
n=read();m=read();
scanf("%s",s+);
len = strlen(s+);
if(n*m>len||n*m*<len){
puts("Impossible");
continue;
}
fo(i,,len) s[i]-='';
if(gao()){
fo(i,,n){
putchar(''+a[i]);
}
putchar(' ');
fo(i,,m){
putchar(''+b[i]);
}
putchar('\n');
}else{
puts("Impossible");
}
}
return ;
}
2018 icpc 青岛的更多相关文章
- 2018 icpc 青岛网络赛 J.Press the Button
Press the Button Time Limit: 1 Second Memory Limit: 131072 KB BaoBao and DreamGrid are playing ...
- 2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)
BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. Among ...
- 2018 ICPC 沈阳网络赛
2018 ICPC 沈阳网络赛 Call of Accepted 题目描述:求一个算式的最大值与最小值. solution 按普通算式计算方法做,只不过要同时记住最大值和最小值而已. Convex H ...
- 2018 ICPC 徐州网络赛
2018 ICPC 徐州网络赛 A. Hard to prepare 题目描述:\(n\)个数围成一个环,每个数是\(0\)~\(2^k-1\),相邻两个数的同或值不为零,问方案数. solution ...
- 2018 ICPC Asia Singapore Regional A. Largest Triangle (计算几何)
题目链接:Kattis - largesttriangle Description Given \(N\) points on a \(2\)-dimensional space, determine ...
- 2018 ICPC Pacific Northwest Regional Contest I-Inversions 题解
题目链接: 2018 ICPC Pacific Northwest Regional Contest - I-Inversions 题意 给出一个长度为\(n\)的序列,其中的数字介于0-k之间,为0 ...
- 2016 ICPC青岛站---k题 Finding Hotels(K-D树)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5992 Problem Description There are N hotels all over ...
- 2018.9青岛网络预选赛(B)
传送门:Problem(B) https://www.cnblogs.com/violet-acmer/p/9664805.html 参考资料: https://blog.csdn.net/qq_40 ...
- 2018.9青岛网络预选赛(K)
传送门:Problem K https://www.cnblogs.com/violet-acmer/p/9664805.html 题意: 给你n个数,找出满足条件的最多的数的个数. 题解: 满足条件 ...
随机推荐
- 在ubuntu上使用Openresty+lua实现WAF----折腾笔记
1.1 参考loveshell的waf实现思路,再此感谢下面其中一部分是转载 1.2 WAF的功能 支持IP白名单和黑名单功能,直接将黑名单的IP访问拒绝.支持URL白名单,将不需要过滤的URL进行定 ...
- MHA ssh检查,repl复制检查和在线切换日志分析
一.SSh 检查日志分析 执行过程及对应的日志: 1.读取MHA manger 节点上的配置文件 2.根据配置文件,得到各个主机的信息,逐一进行SSH检查 3.每个主机都通过SSH连接除了自己以外的其 ...
- 解决ssh登录很慢的问题以及jumpserver登录主机出现:Authentication timeout
一.问题 登录ssh输入用户名后,等待很长时间20-30秒左右才显示输入密码提示框,从而导致通过jumpserver堡垒机登录主机时,报错:Authentication timeout Opt> ...
- SpringBootMVC02——Spring Data JPA的使用&JSP的使用
Spring Data JPA的使用 实体层 package com.littlepage.domain; import javax.persistence.Entity; import javax. ...
- Codeforces1238F. The Maximum Subtree(树形dp)
题目链接:传送门 思路: 题意说用线段的相交作为边,来构造树,所以不存在大于等于3个的线段两两相交,否则会构成环.因而构造出的树中,每个点最多只会与2个度大于1的节点相邻. 不妨把1设为树根,用deg ...
- HashMap的底层实现以及解决hash值冲突的方式
class HashMap<K,V> extends AbstractMap<K,V> HashMap put() HashMap get() 1.put() HashMa ...
- CentOS升级乱七八糟问题解决
----------------------------------------------------------------- Error: Package: libgpod--.el7.x86_ ...
- 【LuoguP5289】[十二省联考2019] 皮配
题目链接 题目描述 略 Sol 一道背包问题 首先暴力做法设 \(dp[i][j][k]\) 表示前 \(i\) 个城市的学校被分到第一阵营 \(j\) 人 第一门派 \(k\) 人的方案数. 中间一 ...
- 百度地图api的简单应用(一):POI检索
使用之前,需要注册一个百度地图开发者账号,最好申请一个认证以获取更高的使用配额和并发上限. 注册之后,申请一个应用,获得一个ak(密钥),并填写ip地址白名单.(这里我使用0.0.0.0/0,查了自己 ...
- kafka——分布式的消息队列系统
总听公司人说kafka kafka... 所以这玩意到底是个啥? 好像是一个高级版的消息队列,什么高吞吐量,数据持久,消息均衡,emmm https://blog.csdn.net/nawenqian ...