UVA 512 - Spreadsheet Tracking 模拟 WA了一天,莫名其妙的A了

这个题我WA到第10次的时候气得我睡觉去了

以前的写法是把操作和源格子都存起来,每一步操作对所有格子都做一遍,总共只做一遍操作

AC的写法是把操作存起来,来一个格子就做一遍操作

道理上都是一样的,第一种写法死活过不去,拿着代码仓库里面的UVA512.in做输入和标答对了一遍,一模一样,绝对是in不够的缘故

除了EX操作之外,对输入的一串操作数排序,在上面二分找小于等于当前值的个数,比直接一个个比要快一些

图方便把4个操作写在一起了,简洁嘛。

代码:

#include <vector>
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;
using pa=pair<int,int>;

vector<string> com;
vector<vector<int>> opn;
vector<int> tv;//temporary vector
string str;
int kcase=1,npa,ncom,a,r,c;
pa p,ans;
vector<int>::iterator bsearch(vector<int>::iterator le,vector<int>::iterator ri,int value);

int main(){
	ios_base::sync_with_stdio(false);
	while(cin>>r>>c&&r+c){
		if(kcase-1)
			cout<<endl;
        cout<<"Spreadsheet #"<<kcase++<<"\n";
		cin>>ncom;
		for(int i=0;i<ncom;++i){
			cin>>str;
			com.push_back(str);
			if(str=="EX"){
				tv.resize(4);
				for(int& x:tv)cin>>x;
				opn.push_back(tv);
			}
			else{
				cin>>a;
				tv.resize(a);
				for(int& x:tv)cin>>x;
				sort(tv.begin(),tv.end());
				opn.push_back(tv);
			}
		}

		cin>>npa;
		while(npa--){
            cin>>p.first>>p.second;
            ans=p;
            for(int i=0;i<ncom;++i)
            if(com[i]=="EX"){
                if(make_pair(opn[i][0],opn[i][1])==ans)
                    ans=make_pair(opn[i][2],opn[i][3]);
                else if(make_pair(opn[i][2],opn[i][3])==ans)
                    ans=make_pair(opn[i][0],opn[i][1]);
            }
            else{
                bool f=(com[i][1]=='R');
                int sym=((com[i][0]=='I')<<1)-1;
                auto tfun=[&f]()->int&{return f?ans.first:ans.second;};
                if(ans.first==-1||ans.second==-1)
                    i=ncom;
                else{
                    if(tfun()<opn[i][0])
                        continue;
                    else if(tfun()>opn[i].back())
                        tfun()+=sym*opn[i].size();
                    else{
                        auto it=bsearch(opn[i].begin(),opn[i].end()-1,tfun());
                        if(sym==-1&&tfun()==*it)
                            tfun()=-1;
                        else
                            tfun()+=sym*(it-opn[i].begin()+1);
                    }
                }
            }

            cout<<"Cell data in ("<<p.first<<','<<p.second<<") ";
            if(ans.first==-1||ans.second==-1)
                cout<<"GONE\n";
            else
                cout<<"moved to ("<<ans.first<<','<<ans.second<<")\n";
		}
		com.clear();opn.clear();
	}
	return 0;
}

vector<int>::iterator bsearch(vector<int>::iterator le,vector<int>::iterator ri,int value){
    auto mid=le;
    while(ri>le){
        mid=le+((ri+1-le)>>1);
        if(*mid<=value)
            le=mid;
        else
            ri=mid-1;
    }
    return le;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值