After you had helped George and Alex to move in the dorm, they went to help their friend Fedor play a new computer game «Call of Soldiers 3».
The game has (m + 1) players and n types of soldiers in total. Players «Call of Soldiers 3» are numbered form 1 to (m + 1). Types of soldiers are numbered from 0 to n - 1. Each player has an army. Army of the i-th player can be described by non-negative integer xi. Consider binary representation of xi: if the j-th bit of number xi equal to one, then the army of the i-th player has soldiers of the j-th type.
Fedor is the (m + 1)-th player of the game. He assume that two players can become friends if their armies differ in at most k types of soldiers (in other words, binary representations of the corresponding numbers differ in at most k bits). Help Fedor and count how many players can become his friends.
The first line contains three integers n, m, k (1 ≤ k ≤ n ≤ 20; 1 ≤ m ≤ 1000).
The i-th of the next (m + 1) lines contains a single integer xi (1 ≤ xi ≤ 2n - 1), that describes the i-th player's army. We remind you that Fedor is the (m + 1)-th player.
Print a single integer — the number of Fedor's potential friends.
7 3 1 8 5 111 17
0
3 3 3 1 2 3 4
3
水题,看前m个数有多少个和第m+1个数二进制不相同位数小于k。
代码:
/**
* @author neko01
*/
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define pb push_back
#define mp(a,b) make_pair(a,b)
#define clr(a) memset(a,0,sizeof a)
#define clr1(a) memset(a,-1,sizeof a)
#define dbg(a) printf("%d\n",a)
typedef pair<int,int> pp;
const double eps=1e-8;
const double pi=acos(-1.0);
int a[1111];
int main()
{
int n,m,k,x;
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<m;i++)
scanf("%d",&a[i]);
scanf("%d",&x);
int ans=0;
for(int i=0;i<m;i++)
{
int sum=0;
for(int j=0;j<n;j++)
if(((1<<j)&a[i])!=((1<<j)&x)) sum++;
if(sum<=k) ans++;
}
printf("%d\n",ans);
return 0;
}
The new ITone 6 has been released recently and George got really keen to buy it. Unfortunately, he didn't have enough money, so George was going to work as a programmer. Now he faced the following problem at the work.
Given a sequence of n integers p1, p2, ..., pn. You are to choose k pairs of integers:
in such a way that the value of sum is maximal possible. Help George to cope with the task.
The first line contains three integers n, m and k (1 ≤ (m × k) ≤ n ≤ 5000). The second line contains n integers p1, p2, ..., pn (0 ≤ pi ≤ 109).
Print an integer in a single line — the maximum possible value of sum.
5 2 1 1 2 3 4 5
9
7 1 3 2 10 7 18 5 33 0
61
水dp,dp[i][j]表示到第i个数有j段的最大值,dp[i][j]=max(dp[i-1][j],dp[i-m][j-1]+sum(i-m,i))
代码:
/**
* @author neko01
*/
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define pb push_back
#define mp(a,b) make_pair(a,b)
#define clr(a) memset(a,0,sizeof a)
#define clr1(a) memset(a,-1,sizeof a)
#define dbg(a) printf("%d\n",a)
typedef pair<int,int> pp;
const double eps=1e-9;
const double pi=acos(-1.0);
const int N=5005;
LL dp[N][N];
LL sum[N];
int a[N];
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++)
{
if(i>=m)
dp[i][j]=max(dp[i-1][j],dp[i-m][j-1]+(sum[i]-sum[i-m]));
else
dp[i][j]=dp[i-1][j];
}
}
printf("%I64d\n",dp[n][k]);
return 0;
}
After you had helped Fedor to find friends in the «Call of Soldiers 3» game, he stopped studying completely. Today, the English teacher told him to prepare an essay. Fedor didn't want to prepare the essay, so he asked Alex for help. Alex came to help and wrote the essay for Fedor. But Fedor didn't like the essay at all. Now Fedor is going to change the essay using the synonym dictionary of the English language.
Fedor does not want to change the meaning of the essay. So the only change he would do: change a word from essay to one of its synonyms, basing on a replacement rule from the dictionary. Fedor may perform this operation any number of times.
As a result, Fedor wants to get an essay which contains as little letters «R» (the case doesn't matter) as possible. If there are multiple essays with minimum number of «R»s he wants to get the one with minimum length (length of essay is the sum of the lengths of all the words in it). Help Fedor get the required essay.
Please note that in this problem the case of letters doesn't matter. For example, if the synonym dictionary says that word cat can be replaced with word DOG, then it is allowed to replace the word Cat with the word doG.
The first line contains a single integer m (1 ≤ m ≤ 105) — the number of words in the initial essay. The second line contains words of the essay. The words are separated by a single space. It is guaranteed that the total length of the words won't exceed 105 characters.
The next line contains a single integer n (0 ≤ n ≤ 105) — the number of pairs of words in synonym dictionary. The i-th of the next n lines contains two space-separated non-empty words xi and yi. They mean that word xi can be replaced with word yi (but not vise versa). It is guaranteed that the total length of all pairs of synonyms doesn't exceed 5·105 characters.
All the words at input can only consist of uppercase and lowercase letters of the English alphabet.
Print two integers — the minimum number of letters «R» in an optimal essay and the minimum length of an optimal essay.
3 AbRb r Zz 4 xR abRb aA xr zz Z xr y
2 6
2 RuruRu fedya 1 ruruRU fedor
1 10
题意:给m个单词,然后给n组变换,表示前一个单词可以变成后一个,求原来m个单词的一种变换使字母r数尽可能少,相同则取单词总长度最小。
容易想到map离散化后给可以转换的连边建图,这个图可能存在环,所以就tarjan缩下点,每个强连通分量取r最少的长度短的,这样就变为一个新的有向无环图,在这个图上dp,一个点u的r数量是它可以达到的点的最小的,然后就完了。注意有极端数据结果会超int
/**
* @author neko01
*/
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define pb push_back
#define mp(a,b) make_pair(a,b)
#define clr(a) memset(a,0,sizeof a)
#define clr1(a) memset(a,-1,sizeof a)
#define dbg(a) printf("%d\n",a)
typedef pair<int,int> pp;
const int INF=0x3f3f3f3f;
const double eps=1e-9;
const double pi=acos(-1.0);
const int N=500005;
const int M=500005;
int head[N];
int dfn[N],low[N];
int belong[N]; //节点i属于哪个强连通分量
int num[N]; //强连通分量i的节点数
bool isstack[N]; //是否在栈中
int stack[N];
vector<int>g[N];
struct Edge{
int to,next;
}edge[M];
int scc,top,cnt,tol; //强连通分量个数,栈顶,时间戳
pp f[N]; //每个单词信息
pp F[N];
int word[N];
char s[N];
bool vis[N];
int T=0; //单词总数
map<string,int>mymap;
void init()
{
clr1(head);
clr(dfn);
//clr(isstack);
//scc=top=cnt=tol=0;
}
void add(int u,int v)
{
edge[tol].to=v;
edge[tol].next=head[u];
head[u]=tol++;
}
void tarjan(int u)
{
dfn[u]=low[u]=++cnt;
stack[++top]=u;
isstack[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(isstack[v]) //回边
{
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u])
{
int t;
scc++;
F[scc]=mp(INF,INF);
do
{
t=stack[top--];
isstack[t]=0;
belong[t]=scc;
F[scc]=min(F[scc],f[t]);
}while(u!=t);
}
}
int input()
{
scanf("%s",s);
int num1=0,num2=strlen(s);
for(int i=0;i<num2;i++)
{
s[i]=tolower(s[i]);
num1+=s[i]=='r';
}
string he=s;
if(mymap[s]!=0)
return mymap[he];
mymap[he]=++T;
f[T]=mp(num1,num2);
return T;
}
void dfs(int u)
{
vis[u]=true;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(!vis[v]) dfs(v);
F[u]=min(F[v],F[u]);
}
}
int main()
{
int m,n;
scanf("%d",&m);
for(int i=0;i<m;i++)
word[i]=input();
scanf("%d",&n);
init();
for(int i=0;i<n;i++)
{
int u=input();
int v=input();
add(u,v);
}
for(int i=1;i<=T;i++)
if(!dfn[i]) tarjan(i);
for(int i=1;i<=T;i++)
{
for(int j=head[i];j!=-1;j=edge[j].next)
{
int u=belong[i];
int v=belong[edge[j].to];
if(u!=v) g[u].pb(v);
}
}
for(int i=1;i<=scc;i++)
dfs(i);
LL ans1=0,ans2=0;
for(int i=0;i<m;i++)
{
int x=belong[word[i]];
ans1+=F[x].first;
ans2+=F[x].second;
}
printf("%I64d %I64d\n",ans1,ans2);
return 0;
}