A:水题,读懂题意就不难了。
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<map>
#include<set>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
#define ll __int64
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
//#pragma comment(linker,"/STACK:1024000000,1024000000")
int n,m;
#define M 110
#define N 2000010
#define Mod 258280327
#define p(x,y) make_pair(x,y)
int a[110][110];
int vote[110];
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
while(sfd(n,m)!=EOF){
memset(vote,0,sizeof vote);
for(int i=1;i<=m;i++){
int flag,mmax=-1;
for(int j=1;j<=n;j++){
sf(a[i][j]);
if(a[i][j]>mmax){
mmax = a[i][j];
flag = j;
}
}
vote[flag]++;
}
int ans,mmax=-1;
for(int i=1;i<=n;i++){
if(mmax<vote[i]){
mmax = vote[i];
ans = i;
}
}
printf("%d\n",ans);
}
return 0;
}
B:其实稍微理解下,就能发现,如果要使得获胜概率较大,那么不是m-1就是m+1。但是这道题目还有个坑。。就是当n=1时,那么我们选的数就只能是1了。。
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<map>
#include<set>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
#define ll __int64
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
//#pragma comment(linker,"/STACK:1024000000,1024000000")
int n,m;
#define M 110
#define N 2000010
#define Mod 258280327
#define p(x,y) make_pair(x,y)
int a[110][110];
int vote[110];
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
while(sfd(n,m)!=EOF){
int res1 = m-1;
int res2 = n-m;
if(n == 1)
printf("%d\n",n);
else if(res1>=res2&&res1>=1)
printf("%d\n",m-1);
else if(res1<res2&&m+1<=n)
printf("%d\n",m+1);
}
return 0;
}
C:这道题目犯了好多傻逼的错误。。刚开始我竟然用了直接模拟的做法。。妥妥的超时了。正解是开始我们先用模拟计算出原字符串的performing次数ans,然后对于每一次的修改,假设修改的位置是x,那么我们记x-1和x+1位置上为’.’的个数是res,那么如果修改成的是’.’,结果就是ans+res;如果修改成的不是’.’,那么结果就是ans-res.这个结论只要自己手写一遍就看得出来。不过我又犯了个错误,就是当它修改时,我们要先判断修改的种类是否发生变化,即如果原来位置本来就是’.’,那我们修改完还是’.’,或者本来位置是字母,修改完还是字母,那这个就不会影响performing的次数了。
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<map>
#include<set>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
#define ll __int64
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
//#pragma comment(linker,"/STACK:1024000000,1024000000")
int n,m;
#define M 110
#define N 300010
#define Mod 258280327
#define p(x,y) make_pair(x,y)
char ch[N];
//char tmp[N];
int solve(){
int ans=0;
stack<char>s;
for(int i=0;i<n;i++){
while(!s.empty() &&s.top() == '.' && ch[i] == '.' && i<n){
i++;
ans++;
}
s.push(ch[i]);
}
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
while(sfd(n,m)!=EOF){
sfs(ch);
int x;
char cr;
int ans = solve();
for(int i=0;i<m;i++){
scanf("%d %c",&x,&cr);
x--;
int res=0;
if(ch[x] == '.' && cr == '.'){
printf("%d\n",ans);
continue;
}
if((ch[x]>='a'&&ch[x]<='z') && (cr>='a'&&cr<='z')){
printf("%d\n",ans);
continue;
}
if(x-1>=0 && ch[x-1] == '.') res++;
if(x+1<n && ch[x+1] == '.') res++;
if(cr == '.')
ans += res;
else
ans -= res;
ch[x] = cr;
printf("%d\n",ans);
}
}
return 0;
}
D:这个参照了别人的想法,自己写的超时了。
首先我们要知道给你几个字母,它们是否能组成一个回文子串的条件是 含有奇数个数的字母要么为0,要么为1,对应的就是组成偶数长度和奇数长度的回文子串。
这里我们用二进制来表示是否含有某个字母,假设输入的是ch,那么每个位置上的表示就是1<<(ch[i]-‘a’)。
预处理的时候,我们将相同高度的点存放在一个vector里面,vector是一个结构体,有两个参数,一个是搜索的序号,另外一个就是表示状态的二进制表示。
我们知道,如果是在同一个subtree里面,那么它们搜索的次序是连续的,那么我们用in[v]表示v这个点刚开始 被访问的次序序号,out[v]表示v这个点的子树被访问完时的次序序号,这样,当我们每次得到一个v,h时,我们用in[v]和out[v]来标定访问的次序范围,在vector高度为h时进行二分搜索,找到v所在的高度为h的子树,并提取进入该子树和离开该子树时的二进制状态,如果某个二进制状态位为1,说明该字母出现的次数是奇数次。这种字母个数出现次数超过1后,就无法构造回文串。
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<map>
#include<set>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
#define ll __int64
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
//#pragma comment(linker,"/STACK:1024000000,1024000000")
int n,m;
#define M 110
#define N 500010
#define Mod 258280327
#define p(x,y) make_pair(x,y)
char ch[N];
int dth; //搜索序号
struct Node{
int dep,val;
bool operator < (const Node &x) const{
return dep<x.dep;
}
Node(int dep,int val){
this->dep = dep;
this->val = val;
}
};
vector<int> G[N];
int in[N],out[N]; //存储进入点v和离开点v所在子树时的搜索序号
vector<Node>res[N]; //res[i]存储在高度i时的搜索序号和二进制状态
int a[N];
void getLev(int u,int dep){
in[u] = ++dth; //进入点u所在子树时的搜索序号
res[dep].push_back(Node(dth,res[dep][res[dep].size()-1].val^a[u]));
//存储在高度dep时的搜索序号和二进制的状态,此时它经过了点u,点u的二进制状态为a[u]
for(int i=0;i<(int)G[u].size();i++){
int v = G[u][i];
getLev(v,dep+1);
}
out[u] = ++dth; //离开点u所在子树时的搜索序号
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
while(sfd(n,m)!=EOF){
for(int i=0;i<=n;i++) G[i].clear(),res[i].clear();
int x;
for(int i=2;i<=n;i++){
sf(x);
G[x].push_back(i);
}
sfs(ch+1);
memset(in,0,sizeof in);
memset(out,0,sizeof out);
for(int i=1;i<=n;i++){ //初始化点i的二进制状态表示和高度i的初始高度和状态
a[i] = 1<<(ch[i]-'a');
res[i].push_back(Node(0,0));
}
dth=0;
getLev(1,1); //预处理
int v,h;
vector<Node>::iterator l,r;
while(m--){
sfd(v,h);
l = lower_bound(res[h].begin(),res[h].end(),Node(in[v],0)); //>=
r = upper_bound(res[h].begin(),res[h].end(),Node(out[v],0)); //<
//二分搜索高度为h且在子树v里面的所有节点的范围
l--,r--; //l是子树的开始,即v,题目中说子树包括v,所以我们得--;r是离开子树时的状态,这个状态是不包括的,所以也得--.
int state = (*l).val^(*r).val; //提取遍历整个v所在的子树后的二进制状态
int num=0;
for(int i=0;i<26;i++){
if(state & (1<<i)) //判断某个字母的出现次数是否为奇数
num++;
}
if(num>1)
printf("No\n");
else
printf("Yes\n");
}
}
return 0;
}