A
A. BowWow and the Timetable
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
In the city of Saint Petersburg, a day lasts for 21002100 minutes. From the main station of Saint Petersburg, a train departs after 11 minute, 44minutes, 1616 minutes, and so on; in other words, the train departs at time 4k4k for each integer k≥0k≥0. Team BowWow has arrived at the station at the time ss and it is trying to count how many trains have they missed; in other words, the number of trains that have departed strictly before time ss. For example if s=20s=20, then they missed trains which have departed at 11, 44 and 1616. As you are the only one who knows the time, help them!
Note that the number ss will be given you in a binary representation without leading zeroes.
Input
The first line contains a single binary number ss (0≤s<21000≤s<2100) without leading zeroes.
Output
Output a single number — the number of trains which have departed strictly before the time ss.
Examples
input
Copy
100000000
output
Copy
4
input
Copy
101
output
Copy
2
input
Copy
10100
output
Copy
3
Note
In the first example 1000000002=256101000000002=25610, missed trains have departed at 11, 44, 1616 and 6464.
In the second example 1012=5101012=510, trains have departed at 11 and 44.
The third example is explained in the statements.
求1-s-1之间4的幂次方的个数。找规律,分析出二进制长度,答案=长度/2,如果它长度是奇数,且1的个数>1,那么答案再加1。就像1000 就是 1 4 答案=长度/2。10010,就是1 4 16答案=长度/2+1。
#include <algorithm> //STL通用算法
#include <bitset> //STL位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex> //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque> //STL双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL定义运算函数(代替运算符)
#include <limits>
#include <list> //STL线性列表容器
#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持
#include<iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL队列容器
#include <set> //STL 集合容器
#include <sstream> //基于字符串的流
#include <stack> //STL堆栈容器
#include <stdexcept> //标准异常类
#include <streambuf> //底层输入/输出支持
#include <string> //字符串类
#include <utility> //STL通用模板类
#include <vector> //STL动态数组容器
#include <cwchar>
#include <cwctype>
#define ll long long
using namespace std;
//priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 1000000+66;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int n,m;
char ch[maxn];
int main()
{
scanf("%s",ch);
int len=strlen(ch);
int num1=0;
for(int i=0;i<len;i++)if(ch[i]=='1')num1++;
int ans=len/2;
if(len&1&&num1>1)ans++;
printf("%d\n",ans);
}
B. Mislove Has Lost an Array
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Mislove had an array a1a1, a2a2, ⋯⋯, anan of nn positive integers, but he has lost it. He only remembers the following facts about it:
- The number of different numbers in the array is not less than ll and is not greater than rr;
- For each array's element aiai either ai=1ai=1 or aiai is even and there is a number ai2ai2 in the array.
For example, if n=5n=5, l=2l=2, r=3r=3 then an array could be [1,2,2,4,4][1,2,2,4,4] or [1,1,1,1,2][1,1,1,1,2]; but it couldn't be [1,2,2,4,8][1,2,2,4,8] because this array contains 44 different numbers; it couldn't be [1,2,2,3,3][1,2,2,3,3] because 33 is odd and isn't equal to 11; and it couldn't be [1,1,2,2,16][1,1,2,2,16]because there is a number 1616 in the array but there isn't a number 162=8162=8.
According to these facts, he is asking you to count the minimal and the maximal possible sums of all elements in an array.
Input
The only input line contains three integers nn, ll and rr (1≤n≤10001≤n≤1000, 1≤l≤r≤min(n,20)1≤l≤r≤min(n,20)) — an array's size, the minimal number and the maximal number of distinct elements in an array.
Output
Output two numbers — the minimal and the maximal possible sums of all elements in an array.
Examples
input
Copy
4 2 2
output
Copy
5 7
input
Copy
5 1 5
output
Copy
5 31
Note
In the first example, an array could be the one of the following: [1,1,1,2][1,1,1,2], [1,1,2,2][1,1,2,2] or [1,2,2,2][1,2,2,2]. In the first case the minimal sum is reached and in the last case the maximal sum is reached.
In the second example, the minimal sum is reached at the array [1,1,1,1,1][1,1,1,1,1], and the maximal one is reached at the array [1,2,4,8,16][1,2,4,8,16].
猜想规律....
#include <algorithm> //STL通用算法
#include <bitset> //STL位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex> //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque> //STL双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL定义运算函数(代替运算符)
#include <limits>
#include <list> //STL线性列表容器
#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持
#include<iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL队列容器
#include <set> //STL 集合容器
#include <sstream> //基于字符串的流
#include <stack> //STL堆栈容器
#include <stdexcept> //标准异常类
#include <streambuf> //底层输入/输出支持
#include <string> //字符串类
#include <utility> //STL通用模板类
#include <vector> //STL动态数组容器
#include <cwchar>
#include <cwctype>
#define ll long long
using namespace std;
//priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 1000000+66;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int n,m;
char ch[maxn];
int main()
{
scanf("%s",ch);
int len=strlen(ch);
int num1=0;
for(int i=0;i<len;i++)if(ch[i]=='1')num1++;
int ans=len/2;
if(len&1&&num1>1)ans++;
printf("%d\n",ans);
}
C. Anna, Svyatoslav and Maps
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
The main characters have been omitted to be short.
You are given a directed unweighted graph without loops with nn vertexes and a path in it (that path is not necessary simple) given by a sequence p1,p2,…,pmp1,p2,…,pm of mm vertexes; for each 1≤i<m1≤i<m there is an arc from pipi to pi+1pi+1.
Define the sequence v1,v2,…,vkv1,v2,…,vk of kk vertexes as good, if vv is a subsequence of pp, v1=p1v1=p1, vk=pmvk=pm, and pp is one of the shortest paths passing through the vertexes v1v1, ……, vkvk in that order.
A sequence aa is a subsequence of a sequence bb if aa can be obtained from bb by deletion of several (possibly, zero or all) elements. It is obvious that the sequence pp is good but your task is to find the shortest good subsequence.
If there are multiple shortest good subsequences, output any of them.
Input
The first line contains a single integer nn (2≤n≤1002≤n≤100) — the number of vertexes in a graph.
The next nn lines define the graph by an adjacency matrix: the jj-th character in the ii-st line is equal to 11 if there is an arc from vertex ii to the vertex jj else it is equal to 00. It is guaranteed that the graph doesn't contain loops.
The next line contains a single integer mm (2≤m≤1062≤m≤106) — the number of vertexes in the path.
The next line contains mm integers p1,p2,…,pmp1,p2,…,pm (1≤pi≤n1≤pi≤n) — the sequence of vertexes in the path. It is guaranteed that for any 1≤i<m1≤i<m there is an arc from pipi to pi+1pi+1.
Output
In the first line output a single integer kk (2≤k≤m2≤k≤m) — the length of the shortest good subsequence. In the second line output kk integers v1v1, ……, vkvk (1≤vi≤n1≤vi≤n) — the vertexes in the subsequence. If there are multiple shortest subsequences, print any. Any two consecutive numbers should be distinct.
Examples
input
Copy
4 0110 0010 0001 1000 4 1 2 3 4
output
Copy
3 1 2 4
input
Copy
4 0110 0010 1001 1000 20 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
output
Copy
11 1 2 4 2 4 2 4 2 4 2 4
input
Copy
3 011 101 110 7 1 2 3 1 3 2 1
output
Copy
7 1 2 3 1 3 2 1
input
Copy
4 0110 0001 0001 1000 3 1 2 4
output
Copy
2 1 4
Note
Below you can see the graph from the first example:
The given path is passing through vertexes 11, 22, 33, 44. The sequence 1−2−41−2−4 is good because it is the subsequence of the given path, its first and the last elements are equal to the first and the last elements of the given path respectively, and the shortest path passing through vertexes 11, 22 and 44 in that order is 1−2−3−41−2−3−4. Note that subsequences 1−41−4 and 1−3−41−3−4 aren't good because in both cases the shortest path passing through the vertexes of these sequences is 1−3−41−3−4.
In the third example, the graph is full so any sequence of vertexes in which any two consecutive elements are distinct defines a path consisting of the same number of vertexes.
In the fourth example, the paths 1−2−41−2−4 and 1−3−41−3−4 are the shortest paths passing through the vertexes 11 and 44.
最短路。给定一个序列,求它的一个子序列,使得子序列中的两点之间的最短路是要在给定序列上的。
先跑最短路,然后先把p1加入答案中,如果答案中最后一个点到pi的距离小于原始序列中距离,那么更新原始序列中距离,并把pi-1加入到答案中。最后加入pm。
#include <algorithm> //STL通用算法
#include <bitset> //STL位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex> //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque> //STL双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL定义运算函数(代替运算符)
#include <limits>
#include <list> //STL线性列表容器
#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持
#include<iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL队列容器
#include <set> //STL 集合容器
#include <sstream> //基于字符串的流
#include <stack> //STL堆栈容器
#include <stdexcept> //标准异常类
#include <streambuf> //底层输入/输出支持
#include <string> //字符串类
#include <utility> //STL通用模板类
#include <vector> //STL动态数组容器
#include <cwchar>
#include <cwctype>
#define ll long long
using namespace std;
//priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 100+6;
const ll mod=1e9+7;
const int INF=99999999;
int n,m;
char ch[maxn][maxn];
int p[maxn*maxn*maxn];
int dp[maxn][maxn];
void floyed()
{
for(int k=1; k<=n; k++)
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
}
}
}
}
int ans[maxn*maxn*maxn];
void solve()
{
int cnt=0;
ans[++cnt]=p[1];
int dis=0;
for(int i=2;i<=m;i++)
{
int yuan=dp[p[i-1]][p[i]];
dis+=yuan;//当前序列跑的值
int now=dp[ans[cnt]][p[i]];//答案中的最短路
if(dis>now)//如果原序列的>答案中的,那么就更新
{
ans[++cnt]=p[i-1];
dis=dp[ans[cnt]][p[i]];
}
}
ans[++cnt]=p[m];
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++)
{
cout<<ans[i]<<" ";
}
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%s",ch[i]+1);
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
dp[i][j]=(ch[i][j]-'0'?1:INF);
if(i==j)
dp[i][j]=0;
}
}
scanf("%d",&m);
for(int i=1; i<=m; i++)
{
scanf("%d",&p[i]);
}
floyed();
solve();
return 0;
}
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=105;
int g[maxm][maxm];
int p[maxm*maxm*maxm];
int ans[maxm*maxm*maxm],cnt;
int n,m;
void input(){
scanf("%d",&n);
getchar();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
char t=getchar();
g[i][j]=(t=='1')?1:inf;
if(i==j)g[i][j]=0;//记得加这个
}
getchar();
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d",&p[i]);
}
}
void floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
}
}
}
void solve(){
ans[++cnt]=p[1];
int dis=0;//dis为当前点到答案最后一个点的距离
for(int i=2;i<=m;i++){
dis+=g[p[i-1]][p[i]];//累加
if(dis>g[ans[cnt]][p[i]]){//如果超过了最后一个点到当前 点的最短距离
ans[++cnt]=p[i-1];//则把p[i-1]加入答案
dis=g[ans[cnt]][p[i]];//更新dis
}
}
ans[++cnt]=p[m];//记得加入p[m]
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++){
printf("%d ",ans[i]);
}
}
int main(){
input();
floyd();
solve();
return 0;
}