如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。

URAL/1027

来自"NOCOW"

跳转到: 导航, 搜索

就是一道字符串处理的题目,考的就是细心.我的方法就是先删所有的评论,再看所有的表达式是否合法,找表达式的方法是:找第一个")",然后从这里往回找第一个"("再判断是否合法,再删了,再重复这一步就可以了.

program cao;
const
  allow='=+-*/0123456789)(';
 
var
  s,s1:ansistring;
  a,b,c,d,e,f,g,h,i,j,k,l,n,m,p,q:longint;
 
function find_comment:boolean;
var
  i:longint;
begin
  k:=pos('(*',s);
  exit(k<>0);
end;
 
function ok_delete_commet:boolean;
var
  i:longint;
begin
  for i:=k+2 to length(s)-1 do
    if (s[i]='*')and(s[i+1]=')') then
    begin
      delete(s,k,i-k+2);
      exit(true);
    end;
  exit(false);
end;
 
function find_exp:boolean;
var
  i:longint;
begin
  k:=pos(')',s);
  exit(k<>0);
end;
 
function ok_delete_exp:boolean;
var
  i:longint;
begin
  for i:=k-1 downto 1 do
  begin
    if pos(s[i],allow)=0 then exit(false);
    if (s[i]='(') then
    begin
      delete(s,i,k-i+1);
      exit(true);
    end;
  end;
  exit(false);
end;
 
begin
  s:='';
  while not(eof) do
  begin
    readln(s1);
    s:=s+s1;
  end;
  while find_comment do
    if ok_delete_commet=false then begin writeln('NO');halt; end;
  while find_exp do
    if ok_delete_exp=false then begin writeln('NO');halt; end;
  if pos('(',s)<>0 then begin writeln('NO');halt; end;
  writeln('YES');
end.

这道题嘛,字符串处理,整体当做一长串,然后从开头一个一个往后查就行了。
我的代码有一点小trick,就是要在最前面加上某个字符(我加的是‘ ’),否则就可能%&^*$#@!了……
code:

program wx;
  const ss='=+-*/0123456789)(';
  var i,j,k,m,n:longint;
      s,s1:ansistring;
      f1:boolean;
  function check(c:char):boolean;
    begin
      for j:=1 to length(ss) do
        if c=ss[j] then exit(true);
      exit(false);
    end;
  function main:boolean;
    begin
      s:=' '+s;
      for i:=2 to length(s) do
        if f1 then
          begin
            if (s[i]='*')and(s[i+1]=')') then f1:=false;
          end
        else if (s[i]='*')and(s[i-1]='(')
          then f1:=true else
          begin
            if (k>0)and(not check(s[i])) then exit(false);
            if s[i]='(' then inc(k)
              else if s[i]=')' then dec(k);
            if k<0 then exit(false);
          end;
      if f1 or (k<>0) then exit(false);
      exit(true);
    end;
  begin
    s:='';
    while not eof(input) do
      begin
        readln(s1);
        s:=s+s1;
      end;
    if main then writeln('YES')
      else writeln('NO');
  end.
//by zhujf553
#include <iostream>
#include <stdlib.h>
#include <string>
 
using namespace std;
 
string st, tmp;
int len;
 
void init()
{
	while(getline(cin, tmp))
		st += tmp;
}
 
string check()
{
	int i, le = 0;
	bool inn = false;
	len = st.length();
	for(int i = 0 ; i < len ; i++)
	{
		if(st[i] != '*' && inn) 
			continue;
		if(st[i] == '(')
		{
			if(i < len - 1 && st[i + 1] == '*')
				i++, inn = true;
			else
				le++;
			continue;
		}
		if(st[i] == '*')
		{
			if(i < len - 1 && st[i + 1] == ')' && inn)
				i++, inn = false;
			continue;
		}
		if(st[i] >= '0' && st[i] <= '9') 
			continue;
		if(st[i] == '=' || st[i] == '+' || st[i] == '-' || st[i] == '/')
			continue;
		if(st[i] == ')')
		{
			le--;
			if(le < 0) return "NO\n";
			continue;
		}
		if(le == 0) continue;
		return "NO\n";
	}
	if(inn || le > 0) return "NO\n";
	return "YES\n";
}
 
void work()
{
	cout << check();
}
 
int main()
{
	init();
	work();
	return 0;
}
个人工具