1004 Tokitsukaze and Multiple
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6794
题意:含有n个数的序列,相邻的数可以相加成为一个新的数,问最后最多能有多少个数是p的倍数
思路:用set就特别简单,我们现在set里插入0,再用个变量t来表示每个数ai mod p,如果这个t已经存在set里,则说明已经有一个数是p的倍数ans++(因为一个数加上p的倍数再mod p 肯定还是这个数,或者这个数本来就是p的倍数),并将set清空且重新插入0,否则将t插入,直至遍历完。
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <cmath>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <unordered_map>
typedef long long ll;
using namespace std;
int a[100005];
set<int> f;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T; cin >> T;
while(T--)
{
int n,p;cin >> n>>p;
for(int i=1;i<=n;i++)
{
cin >> a[i];
}
f.clear();f.insert(0);
int ans=0,t=0;
for(int i=1;i<=n;i++)
{
t+=a[i]%p;
t=t%p;
if(f.count(t))
{
ans++;
t=0;
f.clear();f.insert(0);
}
f.insert(t);
}
cout << ans << endl;
}
return 0;
} 1009 Parentheses Matching
题意:一个字符串由三种字符 ‘*'、'('、 ')' 组成,我们可以将’*‘替换成其它任意两个或这空字符,如果能使替换后的字符串平衡(例如:"", "()", "(())", "()()", "()(())"),输出字典序最小的结果,否则输出No solution!。
思路:比赛的时候没想出来,单纯的匹配还是不难,难就难到还要求字典序最小,看了下组里其他人a了后的代码,其实就贪心一下,尽可能在最左边变成左括号,在最右边变成右括号,最后需要判断是否满足匹配的字符串即可。我们可以用一个数组来记录一下*的位置,优先使用最前面的。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
char st[100020];
int to[100020];
void solve(int len){
int tmp=0;
for(int i=1;i<=len;i++){
if(st[i]=='(') tmp++;
else if(st[i]==')') {
tmp--;
if(tmp<0) break;
}
}
if(tmp==0){
for(int i=1;i<=len;i++){
if(st[i]!='*') cout<<st[i];
}
cout<<endl;
}
else{
puts("No solution!");
}
}
int main()
{
int t;
cin>>t;
while(t--){
scanf("%s",st+1);
int len =strlen(st+1);
int id=0,pre=0,tmp=0;
for(int i=0;i<=len;i++) to[i]=0; //别用memset,效率太慢,这道题会超时
for(int i=1;i<=len;i++){
if(st[i]=='(') tmp++;
else if(st[i]==')'){
tmp--;
if(tmp<0){
if(to[id]==0) break;
id=to[id];
st[id]='(';
tmp=0;
}
}
else to[pre]=i,pre=i;
}
if(tmp>0){
for(int i=len;i>=1;i--){
if(st[i]=='*') st[i]=')',tmp--;
if(tmp==0) break;
}
}
solve(len);
}
}

京公网安备 11010502036488号