2016#34;百度之星#34; - 资格赛(Astar Round1)(hdu5685(线
副标题[/!--empirenews.page--]
Problem A题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5685 解题思路:可以用线段树求解,但是数据有问题,前期一直re,不晓得哪里错了,看了讨论才知道,数据有问题,后期数据被更正过来。但是 在hdu交时,一直wrong,看别人比赛时的代码都是用乘法逆元做的,还以为自己的做法错了,后来好心人告知,hdu上的数据是比 赛时前期的数据,瞬间吐血。。。 AC代码(线段树):#include <iostream> #include <cstdio> #include <cstring> #define lson id<<1 #define rson id<<1|1 using namespace std; const int MOD = 9973; const int N = 100005; char str[N]; int ans = 0; struct node{ int l,r,val; }tree[N<<2]; void build(int id,int l,int r){ tree[id].l = l; tree[id].r = r; if(l == r){ tree[id].val = str[l]-28; return ; } int mid = (l+r)>>1; build(lson,l,mid); build(rson,mid+1,r); tree[id].val = tree[lson].val*tree[rson].val%MOD; } int query(int id,int r){ if(tree[id].l >= l && tree[id].r <= r) return tree[id].val; int mid = (tree[id].l+tree[id].r)>>1; if(r <= mid) return query(lson,r); if(l > mid) return query(rson,r); return query(lson,mid)*query(rson,r)%MOD; } int main(){ int n; while(~scanf("%d",&n)){ scanf("%s",str+1); int a,b,len = strlen(str+1); build(1,1,len); while(n--){ scanf("%d%d",&a,&b); if(a < 1 || b > len){ printf("%dn",ans); continue; }//如果以后数据被更正过来,可不要此步。 ans = query(1,a,b); printf("%dn",ans); } } return 0; } AC代码(乘法逆元):#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int MOD = 9973; const int N = 100005; char str[N]; int inv[MOD+5],no[N]; int main(){ inv[1] = 1; for(int i = 2; i < MOD; ++i) inv[i] = inv[MOD%i]*(MOD-MOD/i)%MOD; int n; while(~scanf("%d",str); int len = strlen(str); no[0] = 1; for(int i = 0; i < len; ++i) no[i+1] = no[i]*(str[i]-28)%MOD; while(n--){ int a,b; scanf("%d%d",&b); printf("%dn",no[b]*inv[no[a-1]]%MOD); } } return 0; } Problem B题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5686 解题思路:这题hdu数据也有问题,拿比赛时的代码交上去Wrong了,后来才发现这题数据也有问题,n可以等于0.。。。而且等于0时,是输出 一空行。。。 AC代码:import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args) { BigInteger[] dp = new BigInteger[205]; dp[1] = BigInteger.ONE; dp[2] = BigInteger.valueOf(2); for(int i = 3; i <= 200; ++i) dp[i] = dp[i-1].add(dp[i-2]); Scanner sca = new Scanner(System.in); while(sca.hasNext()){ int n = sca.nextInt(); if(n == 0){ System.out.println(); continue; } System.out.println(dp[n]); } } } Problem C题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5687 解题思路:这题题目不难,但是要注意一些细节,比如原来有hello,要你删除he后,剩下的前缀如果值为0了,也要被删除,这点注意好就行 了。(具体细节看deltrie这个函数) AC代码:#include <iostream> #include <cstdio> #include <cstring> using namespace std; struct node{ int cnt; struct node *next[26]; node(){ cnt = 0; memset(next,sizeof(next)); } }; node *root = NULL; char op[10],str[35]; void build(char *s){ node *p = root; int l = strlen(s); for(int i = 0; i < l; i++){ if(p->next[s[i]-'a'] == NULL){ p->next[s[i]-'a'] = new node(); } p = p->next[s[i]-'a']; p->cnt++; } } void del(node *root){ for(int i = 0; i < 26; ++i){ if(root->next[i] != NULL) delete(root->next[i]); } delete root; } void deltrie(char *s){ int l = strlen(s); node *p = root; for(int i = 0; i < l; ++i){ if(p->next[s[i]-'a'] == NULL) return ; p = p->next[s[i]-'a']; } int num = p->cnt; node *q; p = root; for(int i = 0; i < l; ++i){ q = p->next[s[i]-'a']; q->cnt -= num; if(q->cnt == 0){ del(q); p->next[s[i]-'a'] = NULL; return ; } p = p->next[s[i]-'a']; } } bool findtrie(char *s){ node *p = root; int l = strlen(s); for(int i = 0; i < l; i++){ if(p->next[s[i]-'a'] == NULL) return false; p = p->next[s[i]-'a']; } return true; } int main(){ int n; while(~scanf("%d",&n)){ root = new node; for(int i = 0; i < n; ++i){ scanf("%s%s",op,str); if(op[0] == 'i') build(str); else if(op[0] == 'd') deltrie(str); else{ if(findtrie(str)) puts("Yes"); else puts("No"); } } } return 0; } Problem D题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5688 解题思路:直接用map处理即可。。。 AC代码:(编辑:阜新站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |